Ejemplo n.º 1
0
class Reactor(object):

    def __init__(self, redis, events, periodics=[], select=[]):
        self.logger = logging.getLogger('reactor')
        self.selector = Selector(select)
        self.db = ReactorDB(redis)
        self.mapper = dict(self.mapper_gen(events))

        self.periodics = periodics
        self.timeline = SortedDict()

        self.load()

    def time(self):
        return itime()

    def mapper_gen(self, events):
        for event in events:
            yield event.type(), event

    def __getitem__(self, name):
        return self.selector.get(name)

    def add_to_queue(self, event, time):
        self.selector.process(event)
        self.get(time).append(event)

    def load(self):
        for time, event_queue in self.db.event_models:
            for event_db in event_queue:
                event = self.mapper.get(event_db.type.get())
                if event:
                    self.add_to_queue(event(**event_db.params.get()), time=time)

    def flush(self):
        self.timeline.clear()
        self.selector.clear()

    def get(self, time):
        queue = self.timeline.get(time)
        if queue is None:
            queue = self.timeline[time] = []
        return queue

    def append(self, event, tdelta=None, time=None):
        time = time or self.time() + tdelta
        self.add_to_queue(event, time)
        self.db.dump(time, event)
        return time

    def wait_for_calc(self, time):
        done = False
        while self.timeline and not done:
            smallest_time, events = self.timeline.smallest_item()
            if smallest_time <= time:
                yield smallest_time, events
            else:
                done = True

    def remove_events(self, time):
        if time in self.timeline:
            del self.timeline[time]
        self.db.remove_item(time)

    def execute(self, event, time):
        try:
            event.do(self, time)
        except Exception:
            self.logger.error('%s executing at %s' % (event, time), exc_info=1)

    def calc(self, time=None):
        time = time or self.time()

        for event in self.periodics:
            self.execute(event, time)

        for expected_time, events in self.wait_for_calc(time):
            for event in events:
                self.execute(event, time)
                self.selector.remove(event)
            self.remove_events(expected_time)
Ejemplo n.º 2
0
 def test_clear(self):
     a = SortedDict({'a': 1, 'b': 2})
     a.clear()
     self.assertEqual(len(a), 0)
     self.assertTrue('a' not in a)