예제 #1
0
    def play(self):
        '''round-robin'''
        self.open_start_urls()
        loops_without_progress = 0
        while True:
            import time
            start = time.time()
            if len(self.bots) == 0:
                return
            # bots got stuck if there's 2 wait pages in a row
            if loops_without_progress > 10:
                raise AssertionError('Bots got stuck')
            results = Chan(buflen=len(self.bots))
            threads = []
            for bot in self.bots.values():
                if bot.on_wait_page():
                    pass
                else:
                    thread = SubmitThread(bot, results)
                    threads.append(thread)
                    thread.start()

            for thread in threads:
                bot, status = results.get()
                if isinstance(status, Exception):
                    raise status
                elif status == 'finished':
                    del self.bots[bot.participant.id]
                else:
                    bot.submit(status)
            results.close()

            if not threads:
                loops_without_progress += 1
예제 #2
0
    def test_buf_simple(self):
        S = 5
        c = Chan(S)
        for i in range(S):
            c.put(i)
        c.close()

        results = list(c)
        self.assertEqual(results, list(range(S)))
예제 #3
0
    def test_buf_simple(self):
        S = 5
        c = Chan(S)
        for i in range(S):
            c.put(i)
        c.close()

        results = list(c)
        self.assertEqual(results, list(range(S)))
예제 #4
0
class Subscription(object):
    def __init__(self, fetcher):
        self.fetcher = fetcher
        self.updates_chan = Chan()
        self.quit = Chan()
        self.thread = threading.Thread(
            name='Subscription',
            target=self._run)
        #self.thread.daemon = True
        self.thread.start()

    def _run(self):
        next_time = time.time()
        pending = []  # First is most recent.  Should be a deque
        err = None

        while True:
            start_fetch = timeout_after(max(0.0, next_time - time.time()))

            # Does or doesn't wait on updates_chan depending on if we have
            # items ready.
            if pending:
                outchans = [(self.updates_chan, pending[0])]
            else:
                outchans = []

            ch, value = chanselect([self.quit, start_fetch], outchans)
            if ch == self.quit:
                errc = value
                self.updates_chan.close()
                errc.put(err)
                return
            elif ch == start_fetch:
                try:
                    err = None
                    item_list, next_time = self.fetcher.fetch()
                except Exception as ex:
                    err = ex
                    next_time = time.time() + 10.0
                    continue
                pending.extend(item_list)
            else:  # self.updates_chan
                pending.pop(0)  # Pops the sent item

    def updates(self):
        return self.updates_chan

    def close(self):
        errc = Chan()
        self.quit.put(errc)
        result = errc.get()
        self.thread.join(0.2)
        assert not self.thread.is_alive()
        return result
예제 #5
0
class Subscription(object):
    def __init__(self, fetcher):
        self.fetcher = fetcher
        self.updates_chan = Chan()
        self.quit = Chan()
        self.thread = threading.Thread(name='Subscription', target=self._run)
        #self.thread.daemon = True
        self.thread.start()

    def _run(self):
        next_time = time.time()
        pending = []  # First is most recent.  Should be a deque
        err = None

        while True:
            start_fetch = timeout_after(max(0.0, next_time - time.time()))

            # Does or doesn't wait on updates_chan depending on if we have
            # items ready.
            if pending:
                outchans = [(self.updates_chan, pending[0])]
            else:
                outchans = []

            ch, value = chanselect([self.quit, start_fetch], outchans)
            if ch == self.quit:
                errc = value
                self.updates_chan.close()
                errc.put(err)
                return
            elif ch == start_fetch:
                try:
                    err = None
                    item_list, next_time = self.fetcher.fetch()
                except Exception as ex:
                    err = ex
                    next_time = time.time() + 10.0
                    continue
                pending.extend(item_list)
            else:  # self.updates_chan
                pending.pop(0)  # Pops the sent item

    def updates(self):
        return self.updates_chan

    def close(self):
        errc = Chan()
        self.quit.put(errc)
        result = errc.get()
        self.thread.join(0.2)
        assert not self.thread.is_alive()
        return result
예제 #6
0
class Merged(object):
    def __init__(self, subscriptions):
        self.subscriptions = subscriptions
        self.updates_chan = Chan()
        self.quit = Chan()

        self.thread = threading.Thread(
            name="Merged",
            target=self._run)
        self.thread.start()

    def _close_subs_collect_errs(self):
        return [sub.close() for sub in self.subscriptions]

    def _run(self):
        subchans = [sub.updates() for sub in self.subscriptions]
        while True:
            c, value = chanselect(subchans + [self.quit], [])
            if c == self.quit:
                value.put(self._close_subs_collect_errs())
                self.updates_chan.close()
                return
            else:
                item = value

            c, _ = chanselect([self.quit], [(self.updates_chan, item)])
            if c == self.quit:
                value.put(self._close_subs_collect_errs())
                self.updates_chan.close()
                return
            else:
                pass  # Send successful

    def updates(self):
        return self.updates_chan

    def close(self):
        errc = Chan()
        self.quit.put(errc)
        result = errc.get()
        self.thread.join(timeout=0.2)
        assert not self.thread.is_alive()
        return result
예제 #7
0
class Merged(object):
    def __init__(self, subscriptions):
        self.subscriptions = subscriptions
        self.updates_chan = Chan()
        self.quit = Chan()

        self.thread = threading.Thread(name="Merged", target=self._run)
        self.thread.start()

    def _close_subs_collect_errs(self):
        return [sub.close() for sub in self.subscriptions]

    def _run(self):
        subchans = [sub.updates() for sub in self.subscriptions]
        while True:
            c, value = chanselect(subchans + [self.quit], [])
            if c == self.quit:
                value.put(self._close_subs_collect_errs())
                self.updates_chan.close()
                return
            else:
                item = value

            c, _ = chanselect([self.quit], [(self.updates_chan, item)])
            if c == self.quit:
                value.put(self._close_subs_collect_errs())
                self.updates_chan.close()
                return
            else:
                pass  # Send successful

    def updates(self):
        return self.updates_chan

    def close(self):
        errc = Chan()
        self.quit.put(errc)
        result = errc.get()
        self.thread.join(timeout=0.2)
        assert not self.thread.is_alive()
        return result
예제 #8
0
class SolidTimer(object):
    def __init__(self, color, blink=False, period=0.5):
        self.blink = blink
        self.period = period
        self.color = color.split('-')[0]
        self.chan = Chan()
        self._stop = threading.Event()
        self._thread = threading.Thread(name='LightTimer', target=self.run)
        self._thread.daemon = True
        self._thread.start()

    def run(self):
        STATE = []
        if self.color == 'red':
            STATE = [lights.RED1, lights.RED2]
        elif self.color == 'yellow':
            STATE = [lights.YLW1, lights.YLW2]
        elif self.color == 'green':
            STATE = [lights.GRN1, lights.GRN2]

        on = True
        while not self._stop.is_set():
            if on:
                if self.blink:
                    self.chan.put([STATE[0]])
                    on = False
                    time.sleep(self.period)
                else:
                    self.chan.put(STATE)
                    time.sleep(5)
            else:
                self.chan.put([STATE[1]])
                on = True
                time.sleep(self.period)

        self.chan.close()

    def stop(self):
        self._stop.set()
예제 #9
0
class LightTimer(object):
    def __init__(self, period=DEFAULT_PERIOD, yellow=DEFAULT_YELLOW):
        self.period = period
        self.yellow = yellow
        self.trip = False
        self._stop = threading.Event()
        self.chan = Chan()
        self._thread = threading.Thread(name='LightTimer', target=self.run)
        self._thread.daemon = True
        self._thread.start()

    def run(self):
        STATES = [
            [lights.RED1, lights.GRN2],
            [lights.RED1, lights.YLW2],
            [lights.GRN1, lights.RED2],
            [lights.YLW1, lights.RED2],
        ]
        state_i = len(STATES) - 1
        t_last = 0
        while not self._stop.is_set():
            t_yellow = min(0.25 * self.period, DEFAULT_YELLOW)
            t_green = self.period - t_yellow
            dur = t_green if state_i % 2 == 0 else t_yellow

            now = time.time()
            if now > t_last + dur or self.trip:
                t_last = now
                state_i = (state_i + 1) % len(STATES)
                self.chan.put(STATES[state_i])
                self.trip = False
            time.sleep(0.1)
        self.chan.close()

    def stop(self):
        self._stop.set()
예제 #10
0
class LightTimer(object):
    def __init__(self, period=DEFAULT_PERIOD, yellow=DEFAULT_YELLOW):
        self.period = period
        self.yellow = yellow
        self.trip = False
        self._stop = threading.Event()
        self.chan = Chan()
        self._thread = threading.Thread(name='LightTimer', target=self.run)
        self._thread.daemon = True
        self._thread.start()

    def run(self):
        STATES = [
            [lights.RED1, lights.GRN2],
            [lights.RED1, lights.YLW2],
            [lights.GRN1, lights.RED2],
            [lights.YLW1, lights.RED2],
        ]
        state_i = len(STATES) - 1
        t_last = 0
        while not self._stop.is_set():
            t_yellow = min(0.25 * self.period, DEFAULT_YELLOW)
            t_green = self.period - t_yellow
            dur = t_green if state_i % 2 == 0 else t_yellow

            now = time.time()
            if now > t_last + dur or self.trip:
                t_last = now
                state_i = (state_i + 1) % len(STATES)
                self.chan.put(STATES[state_i])
                self.trip = False
            time.sleep(0.1)
        self.chan.close()

    def stop(self):
        self._stop.set()