class _CriticalData: def __init__(self): self._lock = Lock() self._cond = Condition(self._lock) self.state = ConnectionMixin.IDLE self.connection_count = 0 def acquire(self): return self._lock.acquire() def release(self): return self._lock.release() def wait(self, timeout=None): if timeout != None: self._cond.wait(timeout) else: self._cond.wait() def notify(self): self._cond.notify() def increment_connection_count(self): self.connection_count += 1 self.state = ConnectionMixin.UP return self.connection_count def decrement_connection_count(self): self.connection_count -= 1 if self.connection_count < 1: self.state = ConnectionMixin.DOWN def get_state(self): return self.state def set_state(self, state): self.state = state
class _CriticalData: def __init__(self): self._lock = Lock() self._cond = Condition(self._lock) self.state = ConnectionMixin.IDLE self.connection_count = 0 def acquire(self): return self._lock.acquire() def release(self): return self._lock.release() def wait(self, timeout=None): if timeout != None: self._cond.wait(timeout) else: self._cond.wait() def notify(self): self._cond.notify() def increment_connection_count(self): self.connection_count += 1 self.state = ConnectionMixin.UP return self.connection_count def decrement_connection_count(self): self.connection_count -= 1 if self.connection_count <1 : self.state = ConnectionMixin.DOWN def get_state(self): return self.state def set_state(self,state): self.state = state
class __impl(ImmortalThread): tm_counter = Counter(0) def __init__(self, timeout=2.0): self.timeout = timeout self.stations = {} self._monitor = monitor.ChannelMonitor(self.timeout) self.tm_number = self.tm_counter.increment() self._response_tp = ThreadPool(1, 'Jace Response Pool') self._pending_responses = Queue() self._callbacks = {} self._running = False self._sync_get_lock = Lock() self._last_sync_get = uptime.secs() self._cv = Condition() ImmortalThread.__init__(self, None, None, 'Jace Transaction Manager') return def start(self): if not self._monitor.is_running(): self._monitor.start_monitor() self._running = True self._synchronous_transaction = Transaction(self, None, self._bump_cv) self._synchronous_transaction.set_timeout(self.timeout) ImmortalThread.start(self) return def stop(self): msglog.log('Jace', INFO, 'Stop Jace Prism Transaction Manger') if self._monitor.is_running(): self._monitor.stop_monitor() self._running = False return def run(self): msglog.log('Jace', INFO, 'Starting Jace Prism Transaction Manger.') while self._running: try: self.send_loop() self.response_loop() except: msglog.log('Jace', WARN, 'Jace Transaction Manager - error sending next.') msglog.exception() return def transaction_completion_handler(self, transaction): self.tm_number = self.tm_counter.increment() try: tid = transaction.tid s_id, callback = self._callbacks.get(tid) if callback: del self._callbacks[tid] self._pending_responses.put((callback, transaction.get_response())) except: msglog.exception() # recycle the transaction for reuse within the queue self.stations.get(s_id).put_transaction(transaction) return def add_station(self, station): s_id = station.get_id() self.stations[s_id] = station return def get_synchronous(self, station, rqst): self._sync_get_lock.acquire() try: t = self._synchronous_transaction hdr = self._get_auth_header(station) hdr['Connection'] = 'close' t.build_request(rqst.url, None, hdr) self._cv.acquire() try: response = ETimeout() try: t.send_request() self._cv.wait(self.timeout) self._last_sync_get = uptime.secs() if t.is_expired(): t.cancel() else: response = t.get_response() except: t.cancel() finally: self._cv.release() return response finally: self._sync_get_lock.release() return def _bump_cv(self, transaction): # transaction isn't used self._cv.acquire() self._cv.notify() self._cv.release() return def send_loop(self): for s_id, station in self.stations.items(): for i in range(station.transaction_limit): try: t, rqst = station.get_next() except Empty: break hdr = self._get_auth_header(station) hdr['Connection'] = 'close' t.build_request(rqst.url, None, hdr) self._callbacks[t.tid] = (s_id, rqst.callback) t.send_request() return def response_loop(self): while 1: try: callback, rsp = self._pending_responses.get(False) callback(rsp) except Empty: return except: msglog.log('Jace', WARN, 'Unexpected error in response_loop') msglog.exception() return def _get_auth_header(self, station): return {"Authorization": "Basic %s" % station.base64string}
class __impl(ImmortalThread): tm_counter = Counter(0) def __init__(self, timeout=2.0): self.timeout = timeout self.stations = {} self._monitor = monitor.ChannelMonitor(self.timeout) self.tm_number = self.tm_counter.increment() self._response_tp = ThreadPool(1, 'Jace Response Pool') self._pending_responses = Queue() self._callbacks = {} self._running = False self._sync_get_lock = Lock() self._last_sync_get = uptime.secs() self._cv = Condition() ImmortalThread.__init__(self, None, None, 'Jace Transaction Manager') return def start(self): if not self._monitor.is_running(): self._monitor.start_monitor() self._running = True self._synchronous_transaction = Transaction( self, None, self._bump_cv) self._synchronous_transaction.set_timeout(self.timeout) ImmortalThread.start(self) return def stop(self): msglog.log('Jace', INFO, 'Stop Jace Prism Transaction Manger') if self._monitor.is_running(): self._monitor.stop_monitor() self._running = False return def run(self): msglog.log('Jace', INFO, 'Starting Jace Prism Transaction Manger.') while self._running: try: self.send_loop() self.response_loop() except: msglog.log( 'Jace', WARN, 'Jace Transaction Manager - error sending next.') msglog.exception() return def transaction_completion_handler(self, transaction): self.tm_number = self.tm_counter.increment() try: tid = transaction.tid s_id, callback = self._callbacks.get(tid) if callback: del self._callbacks[tid] self._pending_responses.put( (callback, transaction.get_response())) except: msglog.exception() # recycle the transaction for reuse within the queue self.stations.get(s_id).put_transaction(transaction) return def add_station(self, station): s_id = station.get_id() self.stations[s_id] = station return def get_synchronous(self, station, rqst): self._sync_get_lock.acquire() try: t = self._synchronous_transaction hdr = self._get_auth_header(station) hdr['Connection'] = 'close' t.build_request(rqst.url, None, hdr) self._cv.acquire() try: response = ETimeout() try: t.send_request() self._cv.wait(self.timeout) self._last_sync_get = uptime.secs() if t.is_expired(): t.cancel() else: response = t.get_response() except: t.cancel() finally: self._cv.release() return response finally: self._sync_get_lock.release() return def _bump_cv(self, transaction): # transaction isn't used self._cv.acquire() self._cv.notify() self._cv.release() return def send_loop(self): for s_id, station in self.stations.items(): for i in range(station.transaction_limit): try: t, rqst = station.get_next() except Empty: break hdr = self._get_auth_header(station) hdr['Connection'] = 'close' t.build_request(rqst.url, None, hdr) self._callbacks[t.tid] = (s_id, rqst.callback) t.send_request() return def response_loop(self): while 1: try: callback, rsp = self._pending_responses.get(False) callback(rsp) except Empty: return except: msglog.log('Jace', WARN, 'Unexpected error in response_loop') msglog.exception() return def _get_auth_header(self, station): return {"Authorization": "Basic %s" % station.base64string}