Example #1
0
def _heartbeat_loop(gw: 'VoiceGateway', heartbeat_interval: float):
    """
    Heartbeat looper that loops and sends heartbeats to the gateway.

    :param gw: The gateway to handle.
    """
    # async threads!
    logger.debug("Sending initial heartbeat.")
    AWAIT(gw.send_heartbeat())
    while True:
        # this is similar to the normal threaded event waiter
        # it will time out after heartbeat_interval seconds.
        try:
            AWAIT(
                curio.timeout_after(heartbeat_interval,
                                    gw._stop_heartbeating.wait()))
        except curio.TaskTimeout:
            pass
        else:
            break

        try:
            AWAIT(gw.send_heartbeat())
        except ReconnectWebsocket:
            break
Example #2
0
    def readinto(self, memory):
        with memoryview(memory).cast('B') as view:
            remaining = len(view)
            total_read = 0

            # It's possible that there is data already buffered on this stream.
            # If so, we have to copy into the memory buffer first.
            buffered = len(self._buffer)
            tocopy = remaining if (remaining < buffered) else buffered
            if tocopy:
                view[:tocopy] = self._buffer[:tocopy]
                del self._buffer[:tocopy]
                remaining -= tocopy
                total_read += tocopy

            # To emulate behavior of synchronous readinto(), we read all available
            # bytes up to the buffer size.
            while remaining > 0:
                try:
                    nrecv = self._readinto_impl(view[total_read:total_read +
                                                     remaining])

                    # On proper file objects, None might be returned to indicate blocking
                    if nrecv is None:
                        AWAIT(_read_wait, self._fileno)
                    elif nrecv == 0:
                        break
                    else:
                        total_read += nrecv
                        remaining -= nrecv
                except WantRead:
                    AWAIT(_read_wait, self._fileno)
                except WantWrite:
                    AWAIT(_write_wait, self._fileno)
            return total_read
Example #3
0
 def recv(self, maxsize, flags=0):
     while True:
         try:
             return self._socket_recv(maxsize, flags)
         except WantRead:
             AWAIT(_read_wait, self._fileno)
         except WantWrite:
             AWAIT(_write_wait, self._fileno)
Example #4
0
 def do_handshake(self):
     while True:
         try:
             return self._socket.do_handshake()
         except WantRead:
             AWAIT(_read_wait, self._fileno)
         except WantWrite:
             AWAIT(_write_wait, self._fileno)
Example #5
0
 def recvfrom(self, buffersize, flags=0):
     while True:
         try:
             return self._socket.recvfrom(buffersize, flags)
         except WantRead:
             AWAIT(_read_wait, self._fileno)
         except WantWrite:
             AWAIT(_write_wait, self._fileno)
Example #6
0
 def send(self, data, flags=0):
     while True:
         try:
             return self._socket_send(data, flags)
         except WantWrite:
             AWAIT(_write_wait, self._fileno)
         except WantRead:
             AWAIT(_read_wait, self._fileno)
Example #7
0
 def recv_into(self, buffer, nbytes=0, flags=0):
     while True:
         try:
             return self._socket.recv_into(buffer, nbytes, flags)
         except WantRead:
             AWAIT(_read_wait, self._fileno)
         except WantWrite:
             AWAIT(_write_wait, self._fileno)
Example #8
0
 def task():
     task1 = AWAIT(spawn(add, 1, 1))
     task2 = AWAIT(spawn(add, 2, 2))
     task3 = AWAIT(spawn(add, 3, 3))
     w = TaskGroup([task1, task2, task3])
     with w:
         for task in w:
             result = AWAIT(task.join())
             results.append(result)
Example #9
0
 def _read(self, maxbytes=-1):
     while True:
         try:
             data = self._socket_recv(
                 maxbytes if maxbytes > 0 else MAX_READ)
             return data
         except WantRead:
             AWAIT(_read_wait, self._fileno)
         except WantWrite:
             AWAIT(_write_wait, self._fileno)
Example #10
0
 def flush(self):
     if not self._file:
         return
     while True:
         try:
             return self._file.flush()
         except WantWrite:
             AWAIT(_write_wait, self._fileno)
         except WantRead:
             AWAIT(_read_wait, self._fileno)
Example #11
0
    def func():
        with disable_cancellation():
            AWAIT(sleep(1))
            assert True

            with enable_cancellation():
                AWAIT(sleep(2))

            assert isinstance(AWAIT(check_cancellation()), TaskTimeout)

        with pytest.raises(TaskTimeout):
            AWAIT(sleep(2))
Example #12
0
 def sendto(self, bytes, flags_or_address, address=None):
     if address:
         flags = flags_or_address
     else:
         address = flags_or_address
         flags = 0
     while True:
         try:
             return self._socket.sendto(bytes, flags, address)
         except WantWrite:
             AWAIT(_write_wait, self._fileno)
         except WantRead:
             AWAIT(_read_wait, self._fileno)
Example #13
0
 def _read(self, maxbytes=-1):
     while True:
         # In non-blocking mode, a file-like object might return None if no data is
         # available.  Alternatively, we'll catch the usual blocking exceptions just to be safe
         try:
             data = self._file_read(maxbytes)
             if data is None:
                 AWAIT(_read_wait, self._fileno)
             else:
                 return data
         except WantRead:
             AWAIT(_read_wait, self._fileno)
         except WantWrite:
             AWAIT(_write_wait, self._fileno)
Example #14
0
 def sendall(self, data, flags=0):
     with memoryview(data).cast('B') as buffer:
         total_sent = 0
         try:
             while buffer:
                 try:
                     nsent = self._socket_send(buffer, flags)
                     total_sent += nsent
                     buffer = buffer[nsent:]
                 except WantWrite:
                     AWAIT(_write_wait, self._fileno)
                 except WantRead:
                     AWAIT(_read_wait, self._fileno)
         except curio.errors.CancelledError as e:
             e.bytes_sent = total_sent
             raise
Example #15
0
def test_errors(kernel):
    # spawn_thread used on a coroutine
    async def main():
        with pytest.raises(TypeError):
            t = await spawn_thread(simple_coro, 2, 3)

    kernel.run(main)

    # AWAIT used on coroutine outside of async-thread
    with pytest.raises(AsyncOnlyError):
        AWAIT(simple_coro(2,3))

    # Premature result
    async def f():
        t = await spawn_thread(simple_func, 2, 3)
        assert t.state != 'TERMINATED'
        with pytest.raises(RuntimeError):
            r = t.result
        with pytest.raises(RuntimeError):
            e = t.exception

    kernel.run(f)

    # Launching a thread with no target
    async def g():
        from curio.thread import AsyncThread
        t = AsyncThread()
        with pytest.raises(RuntimeError):
            await t.start()

    kernel.run(g)
Example #16
0
 def write(self, data):
     nwritten = 0
     view = memoryview(data).cast('B')
     try:
         while view:
             try:
                 nbytes = self._socket_send(view)
                 nwritten += nbytes
                 view = view[nbytes:]
             except WantWrite:
                 AWAIT(_write_wait, self._fileno)
             except WantRead:
                 AWAIT(_read_wait, self._fileno)
         return nwritten
     except curio.errors.CancelledError as e:
         e.bytes_written = nwritten
         raise
Example #17
0
def TAWAIT(coro, *args, **kwargs):
    '''
    Ensure that the caller is an async thread (promoting if necessary),
    then await for a coroutine
    '''
    if not is_async_thread():
        enable_async()
    return AWAIT(coro, *args, **kwargs)
Example #18
0
 def accept(self):
     while True:
         try:
             client, addr = self._socket.accept()
             client = Socket(client)
             client.__class__ = type(self)
             return client, addr
         except WantRead:
             AWAIT(_read_wait, self._fileno)
Example #19
0
async def run_in_main(func_, *args, **kwargs):
    """
    Run and return `func_(*args, **kwargs)` in the kernel's thread.
    Note that this should only be restricted to tkinter calls.
    """
    # Note: the argument is `func_` to prevent name clashes in `kwargs`.
    # This can become a positional only parameter (introduced in Python
    # 3.8) once curio deprecates its usage in Python 3.6 and 3.7.
    async with spawn_thread():
        return AWAIT(_call(func_, args, kwargs))
Example #20
0
 def connect(self, address):
     try:
         result = self._socket.connect(address)
         if getattr(self, 'do_handshake_on_connect', False):
             self.do_handshake()
         return result
     except WantWrite:
         AWAIT(_write_wait, self._fileno)
     err = self._socket.getsockopt(SOL_SOCKET, SO_ERROR)
     if err != 0:
         raise OSError(err, 'Connect call failed %s' % (address, ))
     if getattr(self, 'do_handshake_on_connect', False):
         self.do_handshake()
Example #21
0
    def write(self, data):
        nwritten = 0
        view = memoryview(data).cast('B')
        try:
            while view:
                try:
                    nbytes = self._file_write(view)
                    if nbytes is None:
                        raise BlockingIOError()
                    nwritten += nbytes
                    view = view[nbytes:]
                except WantWrite as e:
                    if hasattr(e, 'characters_written'):
                        nwritten += e.characters_written
                        view = view[e.characters_written:]
                    AWAIT(_write_wait, self._fileno)
                except WantRead:
                    AWAIT(_read_wait, self._fileno)
            return nwritten

        except curio.errors.CancelledError as e:
            e.bytes_written = nwritten
            raise
Example #22
0
    def close(self,
              code: int = 1000,
              reason: str = "Client disconnect",
              reconnect: bool = False):
        """
        Cancels and closes this websocket.
        """

        # if reconnecting, don't close this as this will kill the websocket prematurely
        if not reconnect:
            self._cancelled.set()
            AWAIT(self._task.cancel(
                blocking=False))  # don't block because it closes by itself

        self._ws.close(code=code, reason=reason)
Example #23
0
async def test():

    toplevel = await current_toplevel()
    canvas = tkinter.Canvas(toplevel, highlightthickness=0)
    canvas.pack(expand=True, fill="both")

    task = await curio.current_task()
    task.next_event = 0  # Make current task an event task
    assert iseventtask(task)

    x = y = None
    lastx = lasty = None

    try:
        async for i, event in aenumerate(aevents()):
            if str(event.type) in {"Enter", "Motion"}:
                x, y = event.x, event.y
                if lastx is None:
                    lastx, lasty = x, y

                canvas.create_line(lastx, lasty, x, y, width=5)
                canvas.create_oval(x - 2, y - 2, x + 2, y + 2, fill="black")
                lastx, lasty = x, y

    except CloseWindow:
        pass

    if False:  # Toggle this to try out `run_in_main`'s power

        async with curio.spawn_thread():
            try:
                print("not in main thread")
                print(toplevel.winfo_exists())

            except RuntimeError as e:
                print(repr(e))

            AWAIT(
                run_in_main(lambda: (
                    print("in main thread"),
                    print(toplevel.winfo_exists()),
                )))

        # Note that `CloseWindow` exceptions don't pop up here
        await curio.sleep(5)
Example #24
0
 def func():
     with pytest.raises(TaskCancelled):
         result = AWAIT(simple_coro(2, 3))
Example #25
0
 def coro():
     with pytest.raises(TypeError):
         result = AWAIT(simple_coro(2, '3'))
Example #26
0
 def coro():
     result = AWAIT(simple_coro(2, 3))
     return result
Example #27
0
 def func2():
     results.append('func2')
     # Awaiting on an async-thread function should work, but it should stay in the same thread
     AWAIT(func1, threading.currentThread())
Example #28
0
 async def worker2():
     async with spawn_thread():
         AWAIT(evt.wait)
         results.append('worker2')
Example #29
0
 def worker1():
     AWAIT(evt.wait)
     results.append('worker1')
Example #30
0
 async def func(x, y):
     async with spawn_thread():
         time.sleep(0.5)
         results.append(AWAIT(simple_coro(x, y)))