예제 #1
0
    def test_reset (self):
        evt = Event()

        # calling reset before send should throw
        self.assertRaises(AssertionError, evt.reset)

        value = 'some stuff'

        def send_to_event ():
            evt.send(value)

        spawn_n(send_to_event)
        self.assertEqual(evt.wait(), value)

        # now try it again, and we should get the same exact value,
        # and we shouldn't be allowed to resend without resetting
        value2 = 'second stuff'
        self.assertRaises(AssertionError, evt.send, value2)
        self.assertEqual(evt.wait(), value)

        # reset and everything should be happy
        evt.reset()

        def send_to_event2 ():
            evt.send(value2)

        spawn_n(send_to_event2)
        self.assertEqual(evt.wait(), value2)
예제 #2
0
    def test_timeout_cancel(self):
        server = listen(('0.0.0.0', 0))
        _, bound_port = server.getsockname()

        done = Event()

        def client_closer(sock):
            while True:
                (conn, addr) = sock.accept()
                conn.close()

        def go():
            desc = connect(('127.0.0.1', bound_port))
            try:
                hubs.trampoline(desc, read=True, timeout=0.1)
            except TimeoutError:
                assert False, "Timed out"

            server.close()
            desc.close()
            done.send()

        spawn_after_local(0, go)

        server_coro = spawn(client_closer, server)
        done.wait()
        kill(server_coro)

        check_hub()
예제 #3
0
파일: sockets.py 프로젝트: inercia/evy
    def connect (self, address):
        """
        Connects to a remote address
        :param address: the remote address, as a IP and port tuple
        """
        if self.act_non_blocking:
            return self.uv_fd.connect(address)
        elif self.uv_handle:
            try:
                did_connect = Event()

                def connect_callback (tcp_handle, error):
                    try:
                        if error:
                            did_connect.send_exception(
                                last_socket_error(error, msg = 'connect error'))
                        else:
                            did_connect.send(0)
                    except Exception, e:
                        did_connect.send_exception(e)

                self.uv_handle.connect(resolve_address(address), connect_callback)
                did_connect.wait(self.gettimeout(), socket.timeout(errno.ETIME, "timed out"))
            except pyuv.error.TCPError, e:
                raise socket.error(*last_socket_error(e.args[0], msg = 'connect error'))
예제 #4
0
    def connect(self, address):
        """
        Connects to a remote address
        :param address: the remote address, as a IP and port tuple
        """
        if self.act_non_blocking:
            return self.uv_fd.connect(address)
        elif self.uv_handle:
            try:
                did_connect = Event()

                def connect_callback(tcp_handle, error):
                    try:
                        if error:
                            did_connect.send_exception(
                                last_socket_error(error, msg='connect error'))
                        else:
                            did_connect.send(0)
                    except Exception, e:
                        did_connect.send_exception(e)

                self.uv_handle.connect(resolve_address(address),
                                       connect_callback)
                did_connect.wait(self.gettimeout(),
                                 socket.timeout(errno.ETIME, "timed out"))
            except pyuv.error.TCPError, e:
                raise socket.error(
                    *last_socket_error(e.args[0], msg='connect error'))
예제 #5
0
    def test_timeout_cancel (self):
        server = listen(('0.0.0.0', 0))
        _, bound_port = server.getsockname()

        done = Event()

        def client_closer (sock):
            while True:
                (conn, addr) = sock.accept()
                conn.close()

        def go ():
            desc = connect(('127.0.0.1', bound_port))
            try:
                hubs.trampoline(desc, read = True, timeout = 0.1)
            except TimeoutError:
                assert False, "Timed out"

            server.close()
            desc.close()
            done.send()

        spawn_after_local(0, go)

        server_coro = spawn(client_closer, server)
        done.wait()
        kill(server_coro)

        check_hub()
예제 #6
0
    def test_execute_async(self):
        done = Event()

        def some_work():
            done.send()

        pool = GreenPool(2)
        pool.spawn(some_work)
        done.wait()
예제 #7
0
    def test_execute_async(self):
        done = Event()

        def some_work():
            done.send()

        pool = GreenPool(2)
        pool.spawn(some_work)
        done.wait()
예제 #8
0
    def recv(self, buflen, flags=0):
        """
        Receive data from the socket. The return value is a string representing the data received.
        The maximum amount of data to be received at once is specified by bufsize. See the Unix
        manual page recv(2) for the meaning of the optional argument flags; it defaults to zero.

        :param buflen: the maximum length we want from to receive from the socket
        :param flags:
        :return:
        """
        if self.act_non_blocking:
            return self.uv_fd.recv(buflen, flags)
        elif self.uv_handle:
            tot_read = len(self.uv_recv_string)
            if tot_read < buflen:

                did_read = Event()

                def read_callback(handle, data, error):
                    try:
                        self.uv_handle.stop_read()
                        if error:
                            if pyuv.errno.errorcode[error] == 'UV_EOF':
                                did_read.send(GreenSocket.EOF)
                            else:
                                did_read.send_exception(
                                    last_socket_error(error, msg='read error'))
                        elif data is None or len(data) == 0:
                            did_read.send(GreenSocket.EOF)
                        else:
                            ## append the data to the buffer and, maybe, stop reading...
                            self.uv_recv_string += data
                            did_read.send()

                    except Exception, e:
                        did_read.send_exception(e)

                ## TODO: we cannot use start_read for UDP!!

                if isinstance(self.uv_handle, pyuv.TCP):
                    self.uv_handle.start_read(read_callback)
                    did_read.wait(self.gettimeout(),
                                  socket.timeout("timed out"))
                elif isinstance(self.uv_handle, pyuv.UDP):
                    raise NotImplementedError(
                        'not implemented yet for UDP sockets')

            ## get the data we want from the read buffer, and keep the rest
            res, self.uv_recv_string = self.uv_recv_string[:
                                                           buflen], self.uv_recv_string[
                                                               buflen:]
            return res
예제 #9
0
파일: sockets.py 프로젝트: inercia/evy
    def recv (self, buflen, flags = 0):
        """
        Receive data from the socket. The return value is a string representing the data received.
        The maximum amount of data to be received at once is specified by bufsize. See the Unix
        manual page recv(2) for the meaning of the optional argument flags; it defaults to zero.

        :param buflen: the maximum length we want from to receive from the socket
        :param flags:
        :return:
        """
        if self.act_non_blocking:
            return self.uv_fd.recv(buflen, flags)
        elif self.uv_handle:
            tot_read = len(self.uv_recv_string)
            if tot_read < buflen:

                did_read = Event()

                def read_callback (handle, data, error):
                    try:
                        self.uv_handle.stop_read()
                        if error:
                            if pyuv.errno.errorcode[error] == 'UV_EOF':
                                did_read.send(GreenSocket.EOF)
                            else:
                                did_read.send_exception(
                                    last_socket_error(error, msg = 'read error'))
                        elif data is None or len(data) == 0:
                            did_read.send(GreenSocket.EOF)
                        else:
                            ## append the data to the buffer and, maybe, stop reading...
                            self.uv_recv_string += data
                            did_read.send()

                    except Exception, e:
                        did_read.send_exception(e)

                ## TODO: we cannot use start_read for UDP!!

                if isinstance(self.uv_handle, pyuv.TCP):
                    self.uv_handle.start_read(read_callback)
                    did_read.wait(self.gettimeout(), socket.timeout("timed out"))
                elif isinstance(self.uv_handle, pyuv.UDP):
                    raise NotImplementedError('not implemented yet for UDP sockets')

            ## get the data we want from the read buffer, and keep the rest
            res, self.uv_recv_string = self.uv_recv_string[:buflen], self.uv_recv_string[buflen:]
            return res
예제 #10
0
    def test_waiting_for_event_timeout (self):
        evt = Event()

        def send_to_event ():
            sleep(10)
            evt.send(0)

        spawn_n(send_to_event)
        try:
            evt.wait(timeout = 0.5)
        except Timeout:
            pass
        except:
            self.fail('Timeout exception not raised')
        else:
            self.fail('Timeout exception not raised')
예제 #11
0
파일: sockets.py 프로젝트: inercia/evy
    def send (self, data, flags = 0):
        """
        Send data to the socket. The socket must be connected to a remote socket. The optional
        flags argument has the same meaning as for recv() above. Returns the number of bytes sent.
        Applications are responsible for checking that all data has been sent; if only some of the
        data was transmitted, the application needs to attempt delivery of the remaining data.
        :param data: the data to send
        :param flags: modifier flags
        :return: the amount of data written to the socket
        """
        if self.act_non_blocking:
            return self.uv_fd.send(data, flags)
        elif self.uv_handle:
            did_write = Event()
            write_len = len(data)

            def write_callback (handle, error):
                try:
                    if error:
                        did_write.send_exception(last_socket_error(error, msg = 'write error'))
                    else:
                        did_write.send(write_len)
                except Exception, e:
                    did_write.send_exception(e)

            self.uv_handle.write(data, write_callback)
            return did_write.wait(self.gettimeout(), socket.timeout(errno.ETIME, "timed out"))
예제 #12
0
    def send(self, data, flags=0):
        """
        Send data to the socket. The socket must be connected to a remote socket. The optional
        flags argument has the same meaning as for recv() above. Returns the number of bytes sent.
        Applications are responsible for checking that all data has been sent; if only some of the
        data was transmitted, the application needs to attempt delivery of the remaining data.
        :param data: the data to send
        :param flags: modifier flags
        :return: the amount of data written to the socket
        """
        if self.act_non_blocking:
            return self.uv_fd.send(data, flags)
        elif self.uv_handle:
            did_write = Event()
            write_len = len(data)

            def write_callback(handle, error):
                try:
                    if error:
                        did_write.send_exception(
                            last_socket_error(error, msg='write error'))
                    else:
                        did_write.send(write_len)
                except Exception, e:
                    did_write.send_exception(e)

            self.uv_handle.write(data, write_callback)
            return did_write.wait(self.gettimeout(),
                                  socket.timeout(errno.ETIME, "timed out"))
예제 #13
0
    def test_reentrant(self):
        pool = GreenPool(1)

        def reenter():
            waiter = pool.spawn(lambda a: a, 'reenter')
            self.assertEqual('reenter', waiter.wait())

        outer_waiter = pool.spawn(reenter)
        outer_waiter.wait()

        evt = Event()

        def reenter_async():
            pool.spawn(lambda a: a, 'reenter')
            evt.send('done')

        pool.spawn(reenter_async)
        evt.wait()
예제 #14
0
    def test_waiting_for_event (self):
        evt = Event()
        value = 'some stuff'

        def send_to_event ():
            evt.send(value)

        spawn_n(send_to_event)
        self.assertEqual(evt.wait(), value)
예제 #15
0
    def test_reentrant(self):
        pool = GreenPool(1)

        def reenter():
            waiter = pool.spawn(lambda a: a, "reenter")
            self.assertEqual("reenter", waiter.wait())

        outer_waiter = pool.spawn(reenter)
        outer_waiter.wait()

        evt = Event()

        def reenter_async():
            pool.spawn(lambda a: a, "reenter")
            evt.send("done")

        pool.spawn(reenter_async)
        evt.wait()
예제 #16
0
파일: test_queue.py 프로젝트: inercia/evy
    def test_two_bogus_waiters (self):
        def do_receive (q, evt):
            Timeout(0, RuntimeError())
            try:
                result = q.join()
                evt.send(result)
            except RuntimeError:
                evt.send('timed out')

        q = Queue()
        e1 = Event()
        e2 = Event()
        spawn(do_receive, q, e1)
        spawn(do_receive, q, e2)
        sleep(0)
        q.put('sent')
        self.assertEquals(e1.wait(), 'timed out')
        self.assertEquals(e2.wait(), 'timed out')
        self.assertEquals(q.get(), 'sent')
예제 #17
0
    def test_two_bogus_waiters(self):
        def do_receive(q, evt):
            Timeout(0, RuntimeError())
            try:
                result = q.join()
                evt.send(result)
            except RuntimeError:
                evt.send('timed out')

        q = Queue()
        e1 = Event()
        e2 = Event()
        spawn(do_receive, q, e1)
        spawn(do_receive, q, e2)
        sleep(0)
        q.put('sent')
        self.assertEquals(e1.wait(), 'timed out')
        self.assertEquals(e2.wait(), 'timed out')
        self.assertEquals(q.get(), 'sent')
예제 #18
0
파일: test_queue.py 프로젝트: inercia/evy
    def test_zero_max_size (self):
        q = Queue(0)

        def sender (evt, q):
            q.put('hi')
            evt.send('done')

        def receiver (evt, q):
            x = q.join()
            evt.send(x)

        e1 = Event()
        e2 = Event()

        spawn(sender, e1, q)
        sleep(0)
        self.assert_(not e1.ready())
        spawn(receiver, e2, q)
        self.assertEquals(e2.wait(), 'hi')
        self.assertEquals(e1.wait(), 'done')
예제 #19
0
    def read(self, rlen):
        did_read = Event()
        def read_callback(loop, path, read_data, errorno):
            if errorno:
                did_read.send_exception(last_file_error(errorno, 'read error on fd:%d' % self.fileno()))
            else:
                did_read.send(read_data)

        roffset = self._fileobj.tell()            
        pyuv.fs.read(self.uv_hub.ptr, self.fileno(), rlen, roffset, read_callback)
        return did_read.wait()
예제 #20
0
파일: sockets.py 프로젝트: inercia/evy
    def shutdown (self, *args):
        """
        Shut down one or both halves of the connection. If how is SHUT_RD, further receives are
        disallowed. If how is SHUT_WR, further sends are disallowed. If how is SHUT_RDWR, further
        sends and receives are disallowed. Depending on the platform, shutting down one half of
        the connection can also close the opposite half (e.g. on Mac OS X, shutdown(SHUT_WR) does
        not allow further reads on the other end of the connection).
        :param args:
        :return:
        """
        if self.uv_handle:
            shudown_event = Event()

            def _shutdown_callback (tcp_handle, error):
                shudown_event.send()

            self.uv_handle.shutdown(_shutdown_callback)
            shudown_event.wait()
        else:
            self.uv_fd.shutdown(*args)
예제 #21
0
    def shutdown(self, *args):
        """
        Shut down one or both halves of the connection. If how is SHUT_RD, further receives are
        disallowed. If how is SHUT_WR, further sends are disallowed. If how is SHUT_RDWR, further
        sends and receives are disallowed. Depending on the platform, shutting down one half of
        the connection can also close the opposite half (e.g. on Mac OS X, shutdown(SHUT_WR) does
        not allow further reads on the other end of the connection).
        :param args:
        :return:
        """
        if self.uv_handle:
            shudown_event = Event()

            def _shutdown_callback(tcp_handle, error):
                shudown_event.send()

            self.uv_handle.shutdown(_shutdown_callback)
            shudown_event.wait()
        else:
            self.uv_fd.shutdown(*args)
예제 #22
0
    def test_zero_max_size(self):
        q = Queue(0)

        def sender(evt, q):
            q.put('hi')
            evt.send('done')

        def receiver(evt, q):
            x = q.join()
            evt.send(x)

        e1 = Event()
        e2 = Event()

        spawn(sender, e1, q)
        sleep(0)
        self.assert_(not e1.ready())
        spawn(receiver, e2, q)
        self.assertEquals(e2.wait(), 'hi')
        self.assertEquals(e1.wait(), 'done')
예제 #23
0
    def test_send (self):
        event1 = Event()
        event2 = Event()

        spawn(event1.send, 'hello event1')
        Timeout(0, ValueError('interrupted'))
        try:
            result = event1.wait()
        except ValueError:
            X = object()
            result = with_timeout(DELAY, event2.wait, timeout_value = X)
            assert result is X, 'Nobody sent anything to event2 yet it received %r' % (result, )
예제 #24
0
파일: test_queue.py 프로젝트: inercia/evy
    def test_two_waiters_one_dies (self):
        def waiter (q, evt):
            evt.send(q.join())

        def do_receive (q, evt):
            Timeout(0, RuntimeError())
            try:
                result = q.get()
                evt.send(result)
            except RuntimeError:
                evt.send('timed out')

        q = Queue()
        dying_evt = Event()
        waiting_evt = Event()
        spawn(do_receive, q, dying_evt)
        spawn(waiter, q, waiting_evt)
        sleep(0)
        q.put('hi')
        self.assertEquals(dying_evt.wait(), 'timed out')
        self.assertEquals(waiting_evt.wait(), 'hi')
예제 #25
0
    def test_two_waiters_one_dies(self):
        def waiter(q, evt):
            evt.send(q.join())

        def do_receive(q, evt):
            Timeout(0, RuntimeError())
            try:
                result = q.get()
                evt.send(result)
            except RuntimeError:
                evt.send('timed out')

        q = Queue()
        dying_evt = Event()
        waiting_evt = Event()
        spawn(do_receive, q, dying_evt)
        spawn(waiter, q, waiting_evt)
        sleep(0)
        q.put('hi')
        self.assertEquals(dying_evt.wait(), 'timed out')
        self.assertEquals(waiting_evt.wait(), 'hi')
예제 #26
0
파일: test_queue.py 프로젝트: inercia/evy
    def test_waiting (self):
        def do_wait (q, evt):
            result = q.join()
            evt.send(result)

        q = Queue()
        e1 = Event()
        spawn(do_wait, q, e1)
        sleep(0)
        self.assertEquals(1, q.join())
        q.put('hi')
        sleep(0)
        self.assertEquals(0, q.join())
        self.assertEquals('hi', e1.wait())
        self.assertEquals(0, q.join())
예제 #27
0
    def test_waiting(self):
        def do_wait(q, evt):
            result = q.join()
            evt.send(result)

        q = Queue()
        e1 = Event()
        spawn(do_wait, q, e1)
        sleep(0)
        self.assertEquals(1, q.join())
        q.put('hi')
        sleep(0)
        self.assertEquals(0, q.join())
        self.assertEquals('hi', e1.wait())
        self.assertEquals(0, q.join())
예제 #28
0
파일: test_queue.py 프로젝트: inercia/evy
    def test_waiters_that_cancel (self):
        q = Queue()

        def do_receive (q, evt):
            Timeout(0, RuntimeError())
            try:
                result = q.join()
                evt.send(result)
            except RuntimeError:
                evt.send('timed out')

        evt = Event()
        spawn(do_receive, q, evt)
        self.assertEquals(evt.wait(), 'timed out')

        q.put('hi')
        self.assertEquals(q.get(), 'hi')
예제 #29
0
    def test_waiters_that_cancel(self):
        q = Queue()

        def do_receive(q, evt):
            Timeout(0, RuntimeError())
            try:
                result = q.join()
                evt.send(result)
            except RuntimeError:
                evt.send('timed out')

        evt = Event()
        spawn(do_receive, q, evt)
        self.assertEquals(evt.wait(), 'timed out')

        q.put('hi')
        self.assertEquals(q.get(), 'hi')
예제 #30
0
class Queue(LightQueue):
    """
    Create a queue object with a given maximum size.

    If *maxsize* is less than zero or ``None``, the queue size is infinite.

    ``Queue(0)`` is a channel, that is, its :meth:`put` method always blocks 
    until the item is delivered. (This is unlike the standard :class:`Queue`, 
    where 0 means infinite size).
    
    In all other respects, this Queue class resembled the standard library,
    :class:`Queue`.
    """
    def __init__(self, maxsize=None):
        LightQueue.__init__(self, maxsize)
        self.unfinished_tasks = 0
        self._cond = Event()

    def _format(self):
        result = LightQueue._format(self)
        if self.unfinished_tasks:
            result += ' tasks=%s _cond=%s' % (self.unfinished_tasks,
                                              self._cond)
        return result

    def _put(self, item):
        LightQueue._put(self, item)
        self._put_bookkeeping()

    def _put_bookkeeping(self):
        self.unfinished_tasks += 1
        if self._cond.ready():
            self._cond.reset()

    def task_done(self):
        """
        Indicate that a formerly enqueued task is complete. Used by queue consumer threads.
        For each :meth:`get <Queue.get>` used to fetch a task, a subsequent call to :meth:`task_done` tells the queue
        that the processing on the task is complete.

        If a :meth:`join` is currently blocking, it will resume when all items have been processed
        (meaning that a :meth:`task_done` call was received for every item that had been
        :meth:`put <Queue.put>` into the queue).

        Raises a :exc:`ValueError` if called more times than there were items placed in the queue.
        """

        if self.unfinished_tasks <= 0:
            raise ValueError('task_done() called too many times')
        self.unfinished_tasks -= 1
        if self.unfinished_tasks == 0:
            self._cond.send(None)

    def join(self):
        """
        Block until all items in the queue have been gotten and processed.

        The count of unfinished tasks goes up whenever an item is added to the queue.
        The count goes down whenever a consumer thread calls :meth:`task_done` to indicate
        that the item was retrieved and all work on it is complete. When the count of
        unfinished tasks drops to zero, :meth:`join` unblocks.
        """
        return self._cond.wait()
예제 #31
0
파일: queue.py 프로젝트: inercia/evy
class Queue(LightQueue):
    """
    Create a queue object with a given maximum size.

    If *maxsize* is less than zero or ``None``, the queue size is infinite.

    ``Queue(0)`` is a channel, that is, its :meth:`put` method always blocks 
    until the item is delivered. (This is unlike the standard :class:`Queue`, 
    where 0 means infinite size).
    
    In all other respects, this Queue class resembled the standard library,
    :class:`Queue`.
    """

    def __init__ (self, maxsize = None):
        LightQueue.__init__(self, maxsize)
        self.unfinished_tasks = 0
        self._cond = Event()

    def _format (self):
        result = LightQueue._format(self)
        if self.unfinished_tasks:
            result += ' tasks=%s _cond=%s' % (self.unfinished_tasks, self._cond)
        return result

    def _put (self, item):
        LightQueue._put(self, item)
        self._put_bookkeeping()

    def _put_bookkeeping (self):
        self.unfinished_tasks += 1
        if self._cond.ready():
            self._cond.reset()

    def task_done (self):
        """
        Indicate that a formerly enqueued task is complete. Used by queue consumer threads.
        For each :meth:`get <Queue.get>` used to fetch a task, a subsequent call to :meth:`task_done` tells the queue
        that the processing on the task is complete.

        If a :meth:`join` is currently blocking, it will resume when all items have been processed
        (meaning that a :meth:`task_done` call was received for every item that had been
        :meth:`put <Queue.put>` into the queue).

        Raises a :exc:`ValueError` if called more times than there were items placed in the queue.
        """

        if self.unfinished_tasks <= 0:
            raise ValueError('task_done() called too many times')
        self.unfinished_tasks -= 1
        if self.unfinished_tasks == 0:
            self._cond.send(None)

    def join (self):
        """
        Block until all items in the queue have been gotten and processed.

        The count of unfinished tasks goes up whenever an item is added to the queue.
        The count goes down whenever a consumer thread calls :meth:`task_done` to indicate
        that the item was retrieved and all work on it is complete. When the count of
        unfinished tasks drops to zero, :meth:`join` unblocks.
        """
        return self._cond.wait()