Beispiel #1
0
 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
Beispiel #2
0
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()