def __init__(self, obj, subscribers, snapshot_manager=None): self.obj = obj self.publisher = Publisher(subscribers) self.lock = threading.RLock() self.master = None self.slave = None self.snapshot_manager = snapshot_manager self.snapshot_timer = None
class CoopyProxy(): def __init__(self, obj, subscribers, snapshot_manager=None): self.obj = obj self.publisher = Publisher(subscribers) self.lock = threading.RLock() self.master = None self.slave = None self.snapshot_manager = snapshot_manager self.snapshot_timer = None def start_snapshot_manager(self, snapshot_time): import time self.snapshot_timer = SnapshotTimer(snapshot_time, self) time.sleep(snapshot_time) self.snapshot_timer.start() def start_master(self, port=8012, password=None, ipc=False): self.server = CopyNet(self.obj, port=port, password=password, ipc=ipc) self.server.start() self.publisher.register(self.server) self.slave = None def start_slave(self, host, port, password=None, ipc=None): self.server = None self.slave = CopyNetSlave(self.obj, self, host=host, password=password, port=port, ipc=ipc) self.slave.start() def __getattr__(self, name): method = method_or_none(self.obj, name) if not method: return getattr(self.obj, name) (readonly,unlocked,abort_exception) = action_check(method) #TODO: re-write if not readonly and hasattr(self, 'slave') and self.slave: raise Exception('This is a slave/read-only instance.') def method(*args, **kwargs): exception = None try: if not unlocked: self.lock.acquire(1) #record all calls to clock.now() self.obj._clock = RecordClock() thread_ident = thread.get_ident() action = Action(thread_ident, name, datetime.now(), args, kwargs) system = None if not readonly: self.publisher.publish_before(action) try: system = action.execute_action(self.obj) except Exception as e: logger.debug(CORE_LOG_PREFIX + 'Error: ' + str(e)) if abort_exception: logger.debug(CORE_LOG_PREFIX + 'Aborting action' + str(action)) if not abort_exception: self.publisher.publish_exception(action) exception = e #restore clock action.results = self.obj._clock.results if not readonly and not abort_exception: self.publisher.publish(action) finally: if not unlocked: self.lock.release() if exception: raise exception return system return method def basedir_abspath(self): disk_journals = (journal for journal in self.publisher.subscribers if hasattr(journal, 'basedir')) return [os.path.join(os.path.abspath(os.getcwd()), journal.basedir) for journal in disk_journals] def take_snapshot(self): if self.slave: self.slave.acquire() self.lock.acquire() if self.snapshot_manager: self.snapshot_manager.take_snapshot(self.obj) self.lock.release() if self.slave: self.slave.release() def close(self): self.publisher.close() logging.shutdown() if self.snapshot_timer: self.snapshot_timer.stop() def shutdown(self): if self.master: self.server.close() if self.slave: self.slave.close()