Fehlerabfang und Leistung in ProcimgWriter.run() verbessert

This commit is contained in:
2017-11-15 11:32:56 +01:00
parent 01515e28c5
commit 8b0e465205

View File

@@ -401,24 +401,10 @@ class ProcimgWriter(Thread):
"""Startet die automatische Prozessabbildsynchronisierung.""" """Startet die automatische Prozessabbildsynchronisierung."""
fh = self._modio._create_myfh() fh = self._modio._create_myfh()
self._adjwait = self._refresh self._adjwait = self._refresh
while not self._work.is_set(): while not self._work.is_set():
ot = default_timer() ot = default_timer()
# Verzögerte Events prüfen
# NOTE: Darf dies VOR der Aktualisierung der Daten gemacht werden?
if self.__eventwork:
for tup_fire in list(self.__dict_delay.keys()):
if tup_fire[0][4] \
and getattr(self._modio.io, tup_fire[1]).value != \
tup_fire[2]:
del self.__dict_delay[tup_fire]
else:
self.__dict_delay[tup_fire] -= 1
if self.__dict_delay[tup_fire] <= 1:
# Verzögertes Event übernehmen und löschen
self._eventq.put(tup_fire, False)
del self.__dict_delay[tup_fire]
# Lockobjekt holen und Fehler werfen, wenn nicht schnell genug # Lockobjekt holen und Fehler werfen, wenn nicht schnell genug
if not self.lck_refresh.acquire(timeout=self._adjwait): if not self.lck_refresh.acquire(timeout=self._adjwait):
warnings.warn( warnings.warn(
@@ -427,16 +413,12 @@ class ProcimgWriter(Thread):
), ),
RuntimeWarning RuntimeWarning
) )
# Verzögerte Events pausieren an dieser Stelle
continue continue
try: try:
fh.seek(0) fh.seek(0)
bytesbuff = bytearray(fh.read(self._modio._length)) bytesbuff = bytearray(fh.read(self._modio._length))
except IOError:
self._gotioerror()
self.lck_refresh.release()
self._work.wait(self._adjwait)
continue
if self._modio._monitoring: if self._modio._monitoring:
# Inputs und Outputs in Puffer # Inputs und Outputs in Puffer
@@ -450,39 +432,47 @@ class ProcimgWriter(Thread):
dev._filelock.release() dev._filelock.release()
else: else:
# Inputs in Puffer, Outputs in Prozessabbild # Inputs in Puffer, Outputs in Prozessabbild
ioerr = False
for dev in self._modio._lst_refresh: for dev in self._modio._lst_refresh:
dev._filelock.acquire() with dev._filelock:
dev._ba_devdata[dev._slc_inp] = bytesbuff[dev._slc_inpoff] dev._ba_devdata[dev._slc_inp] = \
bytesbuff[dev._slc_inpoff]
if self.__eventwork\ if self.__eventwork\
and len(dev._dict_events) > 0 \ and len(dev._dict_events) > 0 \
and dev._ba_datacp != dev._ba_devdata: and dev._ba_datacp != dev._ba_devdata:
self.__check_change(dev) self.__check_change(dev)
try:
fh.seek(dev._slc_outoff.start) fh.seek(dev._slc_outoff.start)
fh.write(dev._ba_devdata[dev._slc_out]) fh.write(dev._ba_devdata[dev._slc_out])
except IOError:
ioerr = True
finally:
dev._filelock.release()
if self._modio._buffedwrite: if self._modio._buffedwrite:
try:
fh.flush() fh.flush()
except IOError:
ioerr = True
if ioerr: except IOError:
self._gotioerror() self._gotioerror()
self.lck_refresh.release() self.lck_refresh.release()
self._work.wait(self._adjwait)
continue continue
self.lck_refresh.release() else:
# Alle aufwecken # Alle aufwecken
self.lck_refresh.release()
self.newdata.set() self.newdata.set()
finally:
# Verzögerte Events prüfen
if self.__eventwork:
for tup_fire in list(self.__dict_delay.keys()):
if tup_fire[0][4] \
and getattr(self._modio.io, tup_fire[1]).value != \
tup_fire[2]:
del self.__dict_delay[tup_fire]
else:
self.__dict_delay[tup_fire] -= 1
if self.__dict_delay[tup_fire] <= 0:
# Verzögertes Event übernehmen und löschen
self._eventq.put(tup_fire, False)
del self.__dict_delay[tup_fire]
# Refresh abwarten
self._work.wait(self._adjwait) self._work.wait(self._adjwait)
# Wartezeit anpassen um echte self._refresh zu erreichen # Wartezeit anpassen um echte self._refresh zu erreichen