def __init__(self): AgentThreadedBase.__init__(self) self.retry_count=0 self.smap={} self.last_retry_count=1 self.retry_count=0 self.db_ok=None self.todo=BoundedList(self.MAX_BACKLOG)
class CouchdbAgent(AgentThreadedBase): MAX_BACKLOG=128 BACKOFF_LIMIT=64 ## seconds MAX_BURST_SIZE=8 C_LOGPARAMS=[("db_creation_error", "error", 2) ,("db_creation_ok", "info", 8) ,("db_unknown_error", "error", 2) ,("db_drop_entry", "warning", 128) ] def __init__(self): AgentThreadedBase.__init__(self) self.retry_count=0 self.smap={} self.last_retry_count=1 self.retry_count=0 self.db_ok=None self.todo=BoundedList(self.MAX_BACKLOG) ## =========================================================================== HANDLERS def h_ready(self): self._try_create() def h_timer_second(self, count): """ Time base """ if not self.ready: return if not self.db_ok: self._doHandleDb() def h_timer_minute(self, count): """ Attempt to flush pending records to the db """ if len(self.todo) == 0: return if not self.db_ok: return count=self.MAX_BURST_SIZE while count!=0 : try: ts, deviceId, sensorId, value=self.todo.pop(0) except IndexError: break r=self._record(deviceId, sensorId, value, ts, retry=False) if r: self.dprint("Retry successful: deviceId(%s) sensorId(%s) value(%s)" % (deviceId, sensorId, value)) count -= 1 def h_sensor(self, deviceId, sensorId, value): """ Keep a map of sensor state """ previousValue=self.smap.get((deviceId, sensorId), None) if previousValue is None or value!=previousValue: self.smap[(deviceId, sensorId)]=value self.dprint(">>> Changed, device(%s) sensor(%s) value(%s)" % (deviceId, sensorId, value)) self._record(deviceId, sensorId, value) ## =========================================================================== HELPERS def _record(self, deviceId, sensorId, value, ts=None, retry=True): """ Record a state change in the database """ if ts is None: ts=time.time() result=False try: d.db.save(ts, deviceId, sensorId, value) result=True if retry: self.dprint("db: save successful!") except d.dbEntryExist: result=None ## unlikely except (d.dbSaveError, d.dbError): self.db_ok=False if retry: self.todo.push((ts, deviceId, sensorId, value)) else: self.pub("log", "db_drop_entry", "Dropped: device(%s) sensor(%s) value(%s)" % (deviceId, sensorId, value)) except Exception,e: self.db_ok=False self.pub("log", "db_unknown_error", "Unknown error whilst recording to database: %s" % str(e)) return result