예제 #1
0
def distributer(inchans, outchans, delay_max=0.5):
    inchans = inchans[:]  # Copy.  Will remove closed chans
    while True:
        try:
            _, value = select(inchans, [])
            time.sleep(random.random() * delay_max)
        except ChanClosed as ex:
            inchans.remove(ex.which)
            continue
        _, _ = select([], [(chan, value) for chan in outchans])
예제 #2
0
    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 = select([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
예제 #3
0
        def sender():
            i = 0
            while True:
                time.sleep(1.0 * random.random())

                chan, _ = select([quit], [(c, "%s: %d" % (msg, i))])
                if chan == quit:
                    quit.put("See you!")
                i += 1
예제 #4
0
 def fanin_until_closed(inchans, outchan):
     inchans = inchans[:]
     while inchans:
         try:
             _, val = select(inchans, [])
             out.put(val)
         except ChanClosed as ex:
             inchans.remove(ex.which)
     out.close()
예제 #5
0
    def _run(self):
        subchans = [sub.updates() for sub in self.subscriptions]
        while True:
            c, value = select(subchans + [self.quit], [])
            if c == self.quit:
                value.put(self._close_subs_collect_errs())
                self.updates_chan.close()
                return
            else:
                item = value

            c, _ = select([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
예제 #6
0
def write_write_default():
    """Two channels can be read and there's a default clause
    Expected output :
    -----------------
    Writing (42|51) to ch(1|2)
    Writing (42|51) to ch(1|2)
    Received number (42|51) from ch(1|2)
    """

    ch1A = Chan()
    ch1B = Chan()
    ch2A = Chan()
    ch2B = Chan()

    def read_channel1():
        """Read the value in ch1A and write it in ch1B"""
        py_output.write('Reading from ch1\n'.encode())
        x = ch1A.get()
        ch1B.put(x)

    def read_channel2():
        """Read the value in ch2A and write it in ch2B"""
        py_output.write('Reading from ch2\n'.encode())
        x = ch2A.get()
        ch2B.put(x)

    go(read_channel1)
    go(read_channel2)

    time.sleep(0.1)
    # Hopefully this is enough time to let
    # the other two goroutines block on their channel writes

    nb1 = 42
    nb2 = 51
    sent = 0

    chan, nb = select(consumers=[],
                      producers=[(ch1A, 42), (ch2A, 51)],
                      default=True)
    if chan == ch1A:
        py_output.write('Sent number 42 to ch2\n'.encode())
        sent = nb1
    elif chan == ch2A:
        py_output.write('Sent number 51 to ch2\n'.encode())
        sent = nb2
    elif chan == 'default':
        raise Exception('Selected default behavior')

    if sent == 42:  # ch1.put(42) happened
        ch2A.put(17)
        assert ch1B.get() == 42, "We should be able to read 42 from ch1B"
    elif sent == 51:  # ch2.put(51) happened
        ch1A.put(17)
        assert ch2B.get() == 51, "We should be able to read 51 from ch2B"
    else:
        raise Exception('WTF ?')
예제 #7
0
def read_write_default():
    """One channel can be read, the written and there's a default clause
    Expected output :
    -----------------
    (Writing 42 to ch1|Reading from ch2)
    (Writing 42 to ch1|Reading from ch2)
    (Received number 42 from ch1|Sent number 51 to ch2)
    """

    ch1 = Chan()
    ch2 = Chan()

    def write_channel():
        """Write 42 into ch1"""
        py_output.write('Writing 42 to ch1\n'.encode())
        ch1.put(42)

    def read_channel():
        """Read the value in ch2 and write it in ch1"""
        py_output.write('Reading from ch2\n'.encode())
        x = ch2.get()
        ch1.put(x)

    go(write_channel)
    go(read_channel)

    time.sleep(0.1)
    # Hopefully this is enough time to let
    # the other two goroutines block on their channel writes

    nb = 51

    chan, nb = select(consumers=[ch1], producers=[(ch2, 51)], default=True)
    if chan == ch1:
        py_output.write('Received number {} from ch1\n'.format(nb).encode())
    elif chan == ch2:
        py_output.write('Sent number 51 to ch2\n'.encode())
    elif chan == 'default':
        raise Exception('Selected default behavior')

    if nb == 42:  # ch1.get() happened
        ch2.put(17)
        assert ch1.get() == 17, "We should be able to read 17 from ch1"
    elif nb is None:  # ch2.put(51) happened
        assert ch1.get() == 42, "We should be able to read '42' from ch1"
    else:
        raise Exception('WTF ?')
예제 #8
0
def read_read_default():
    """Two channels can be read and there's a default clause
    Expected output :
    -----------------
    Writing (42|51) to ch(1|2)
    Writing (42|51) to ch(1|2)
    Received number (42|51) from ch(1|2)
    """

    ch1 = Chan()
    ch2 = Chan()

    def write_channel1():
        """Write 42 into ch1"""
        py_output.write('Writing 42 to ch1\n'.encode())
        ch1.put(42)

    def write_channel2():
        """Write 51 into ch2"""
        py_output.write('Writing 51 to ch2\n'.encode())
        ch2.put(51)

    go(write_channel1)
    go(write_channel2)

    time.sleep(0.1)
    # Hopefully this is enough time to let
    # the other two goroutines block on their channel writes

    chan, nb = select(consumers=[ch1, ch2], producers=[], default=True)
    if chan == ch1:
        py_output.write('Received number {} from ch1\n'.format(nb).encode())
    elif chan == ch2:
        py_output.write('Received number {} from ch2\n'.format(nb).encode())
    elif chan == 'default':
        raise Exception('Selected default behavior')

    if nb == 42:  # ch1.get() happened
        assert ch2.get() == 51, "We should be able to read '51' from ch2"
    elif nb == 51:  # ch2.get() happened
        assert ch1.get() == 42, "We should be able to read '42' from ch1"
    else:
        raise Exception('WTF ?')
예제 #9
0
def example_timeout():
    def boring(msg):
        c = Chan()

        def sender():
            i = 0
            while True:
                c.put("%s: %d" % (msg, i))
                time.sleep(1.5 * random.random())
                i += 1

        go(sender)
        return c

    c = boring("Joe")
    while True:
        chan, value = select([c, timer(1.0)], [])
        if chan == c:
            print value
        else:
            print "You're too slow."
            return
예제 #10
0
def read_default():
    """The select should execute the default code as many times as needed
    (hopefully once)
    Then the <-ch1 case should happen
    Expected output :
    -----------------
    Selected default behavior
    Writing 42 to ch1
    Received number 42 from ch1 after 1[0-9].[0-9]*µs
    """

    ch1 = Chan()
    ch2 = Chan()

    def write_channel(ch):
        """Wait for ch to be readable and Write an int nb
        into a channel ch"""
        ch.get()
        py_output.write('Writing 42 to ch1\n'.encode())
        ch1.put(42)

    go(write_channel, ch2)

    from_ch1 = 0
    wrote_to_ch2 = False
    start = time.time()
    while from_ch1 == 0:
        chan, nb = select(consumers=[ch1], producers=[], default=True)
        if chan == ch1:
            elapsed = time.time() - start
            from_ch1 = nb
            py_output.write('Received number '
                            '{} from ch1 after '
                            '{}\n'.format(from_ch1, elapsed).encode())
        if chan is 'default':
            py_output.write('Selected default behavior\n'.encode())
            if not wrote_to_ch2:
                ch2.put(1)
                wrote_to_ch2 = True
예제 #11
0
def read():
    """The select should block,
    Then, the <- ch1 case should be executed very soon after
    the other goroutine times out.
    Expected output :
    -----------------
    Writing 42 to ch1
    Waited 1.00[0-9]*s
    """

    ch1 = Chan()

    def write_channel_delayed():
        """Write an int nb into a channel ch with a delay of 1 second"""
        time.sleep(1)
        py_output.write('Writing 42 to ch1\n'.encode())
        ch1.put(42)

    go(write_channel_delayed)

    start = time.time()
    chan, nb = select(consumers=[ch1], producers=[])
    if chan == ch1:
        py_output.write('Waited {}\n'.format(time.time() - start).encode())
예제 #12
0
 def forward():
     while True:
         chan, value = select([input1, input2], [])
         c.put(value)