Exemple #1
0
def current_task(
        loop: Optional[asyncio.AbstractEventLoop]=None
) -> 'asyncio.Task[Any]':
    if PY_37:
        return asyncio.current_task(loop=loop)  # type: ignore
    else:
        return asyncio.Task.current_task(loop=loop)
 async def test_dispatch_event_cancel(self, source):
     """Test that dispatching an event when there are no listeners will still work."""
     source.event_a.connect(lambda event: None)
     future = source.event_a.dispatch()
     future.cancel()
     task = next(t for t in all_tasks() if t is not current_task())
     await task
Exemple #3
0
async def amain(*, args, prog):
	params = docopt.docopt(
		__doc__.replace("\t", " " * 4).format(prog=os.path.basename(prog)),
		argv=args,
		help=True,
		version=True,
		options_first=False
	)
	url = params.pop("URL")
	assert not params, params

	log = asyncio.Queue()
	pending_tasks = []
	printer_task = asyncio.create_task(
		printer(queue=log, fo=sys.stdout)
	)

	git = Git(output_queue=log, git_path="git")

	out = await git.credential("fill", {
		"url": url,
	})
	await log.put(out)

	await asyncio.gather(*pending_tasks)
	current_task, all_tasks = (asyncio.current_task(), asyncio.all_tasks())
	assert {current_task, printer_task} == all_tasks, (current_task, all_tasks)

	await log.put(None)
	await printer_task
Exemple #4
0
def current_task(loop: OptLoop = None) -> 'Task[Any]':
    _loop = loop or asyncio.get_event_loop()  # type: Loop
    if hasattr(asyncio, 'current_task'):
        t = asyncio.current_task(loop=_loop)
    else:
        t = asyncio.Task.current_task(loop=_loop)
    if t is None:
        raise RuntimeError('Loop is not running')
    return t
Exemple #5
0
def current_task(loop: asyncio.AbstractEventLoop) -> asyncio.Task:
    if PY_37:
        task = asyncio.current_task(loop=loop)  # type: ignore
    else:
        task = asyncio.Task.current_task(loop=loop)
    if task is None:
        # this should be removed, tokio must use register_task and family API
        if hasattr(loop, 'current_task'):
            task = loop.current_task()  # type: ignore

    return task
Exemple #6
0
def _task_scope():

    task = asyncio.current_task()
    scope = getattr(task, '_syn_scope', None)

    # no need to lock because it's per-task...
    if scope is None:
        scope = Scope(globscope)
        task._syn_scope = scope

    return scope
Exemple #7
0
def current_task(loop):
    if PY_37:
        task = asyncio.current_task(loop=loop)
    else:
        task = asyncio.Task.current_task(loop=loop)
    if task is None:
        # this should be removed, tokio must use register_task and family API
        if hasattr(loop, 'current_task'):
            task = loop.current_task()

    return task
Exemple #8
0
def varinit(task=None):
    '''
    Initializes (or re-initializes for testing purposes) all of a task's task-local variables

    Precondition:
        If task is None, this must be called from task context
    '''
    if task is None:
        task = asyncio.current_task()
    taskvars = {}
    task._syn_taskvars = taskvars
    return taskvars
Exemple #9
0
async def shutdown(loop, signal=None):
    if signal:
        logging.info(f"Received exit signal {signal.name}...")
    logging.info("Closing database connections")
    logging.info("Nacking outstanding messages")
    tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]

    [task.cancel() for task in tasks]

    logging.info("Cancelling outstanding tasks")
    await asyncio.gather(*tasks, return_exceptions=True)
    logging.info(f"Flushing metrics")
    loop.stop()
Exemple #10
0
async def removetasks(loop):
    tasks = [t for t in asyncio.all_tasks() if t is not
             asyncio.current_task()]

    for task in tasks:
        # skipping over shielded coro still does not help
        if task._coro.__name__ == "cant_stop_me":
            continue
        task.cancel()

    print("Cancelling outstanding tasks")
    await asyncio.gather(*tasks, return_exceptions=True)
    loop.stop()	
Exemple #11
0
 async def handle_connection(self, r, w):
     peername = w.get_extra_info('peername')
     asyncio_utils.set_task_debug_info(
         asyncio.current_task(),
         name=f"Proxyserver.handle_connection",
         client=peername,
     )
     handler = ProxyConnectionHandler(self.master, r, w, self.options)
     self._connections[peername] = handler
     try:
         await handler.handle_client()
     finally:
         del self._connections[peername]
Exemple #12
0
def _run_until_done(coro):
    """execute coroutine, when already in the event loop"""
    loop = asyncio.get_running_loop()
    task = asyncio.current_task()
    asyncio.tasks._unregister_task(task)
    current_task = asyncio.tasks._current_tasks.get(loop)
    assert task == current_task
    del asyncio.tasks._current_tasks[loop]
    runner = loop.create_task(coro)
    while not runner.done():
        loop._run_once()
    asyncio.tasks._current_tasks[loop] = task
    return runner.result()
Exemple #13
0
async def shutdown(loop):
    try:
        all_tasks = asyncio.all_tasks()
        current_task = asyncio.current_task()
    except AttributeError:
        all_tasks = asyncio.Task.all_tasks()
        current_task = asyncio.tasks.Task.current_task()

    tasks = [task for task in all_tasks
             if task is not current_task]
    list(map(lambda task: task.cancel(), tasks))
    await asyncio.gather(*tasks, return_exceptions=True)
    loop.stop()
Exemple #14
0
async def terminate_server(sig: int, loop: asyncio.AbstractEventLoop) -> None:
    if sig == signal.SIGINT and os.isatty(sys.stdout.fileno()):
        # Terminate the line containing ^C
        print()

    await asyncio.gather(*SHUTDOWN, return_exceptions=True)

    tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]
    for task in tasks:
        task.cancel()
    await asyncio.gather(*tasks, return_exceptions=True)

    loop.stop()
Exemple #15
0
    async def stop(self) -> None:
        self.logger.info('shutting down...')
        self.shutdown_event.set()
        tasks = [
            task for task in asyncio.all_tasks()
            if task is not asyncio.current_task()
        ]
        list(map(lambda task: task.cancel(), tasks))

        await asyncio.gather(*tasks, return_exceptions=True)
        self.logger.info('shut down')

        self.loop.stop()
Exemple #16
0
async def shutdown(signal, loop):
    """Cleanup tasks tied to the service's shutdown."""
    print(f"Received exit signal {signal.name}...")
    print("Closing redis connections")
    print("Nacking outstanding messages")
    tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]

    [task.cancel() for task in tasks]

    print(f"Cancelling {len(tasks)} outstanding tasks")
    await asyncio.gather(*tasks, return_exceptions=True)
    print(f"Flushing metrics")
    loop.stop()
Exemple #17
0
async def shutdown_handler(red, signal_type=None):
    if signal_type:
        log.info("%s received. Quitting...", signal_type)
        exit_code = 0
    else:
        log.info("Shutting down from unhandled exception")
        exit_code = 1
    await red.logout()
    await red.loop.shutdown_asyncgens()
    pending = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]
    [task.cancel() for task in pending]
    await asyncio.gather(*pending, loop=red.loop, return_exceptions=True)
    sys.exit(exit_code)
Exemple #18
0
 async def background_stats(self,
                            subs=[
                                "export", "discover", "interfaces",
                                "system-stats", "num-routes",
                                "config-change", "users"
                            ]):
     # self- registering task
     task = asyncio.current_task()
     if task:
         await self.add_task('stats', task)
     with suppress(asyncio.CancelledError):
         async for payload in self.stats(subs):
             pass
Exemple #19
0
 def _get_task(self):
     try:
         # Prevent failure when run from a thread
         # without an event loop.
         loop = asyncio.get_event_loop()
     except RuntimeError:
         return None
     if hasattr(asyncio, 'current_task'):
         # Python 3.7+
         return asyncio.current_task(loop=loop)
     else:
         # Python 3.6 and below
         return asyncio.Task.current_task(loop=loop)
Exemple #20
0
async def shutdown(signal, loop):
    logging.info(f"Received exit signal {signal.name}...")
    logging.info("Closing database connections")
    logging.info("Nacking outstanding messages")
    tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]

    for i, task in enumerate(tasks):
        task.cancel()

    logging.info("Cancelling outstanding tasks")
    await asyncio.gather(*tasks)
    loop.stop()
    logging.info("Shutdown complete.")
Exemple #21
0
 async def _target_consumer():
     while True:
         async with _lock:
             await _lock.wait()
             _async_task_flag["consumer"].append(float(time.time()))
             if (PYTHON_MAJOR_VERSION, PYTHON_MINOR_VERSION) > (3, 6):
                 _async_task_ids["consumer"] = str(
                     id(asyncio.current_task()))
             else:
                 _async_task_ids["consumer"] = str(
                     id(asyncio.Task.current_task()))
         if len(_async_task_flag["producer"]) == 3:
             break
Exemple #22
0
async def shutdown(signal, loop):
    """Cleanup tasks tied to the service's shutdown."""
    logging.info(f'Received exit signal {signal.name}...')
    logging.info('Closing database connections')
    logging.info('Nacking outstanding messages')
    tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]

    [task.cancel() for task in tasks]

    logging.info(f'Cancelling {len(tasks)} outstanding tasks')
    await asyncio.gather(*tasks)
    loop.stop()
    logging.info('Shutdown complete.')
Exemple #23
0
 async def _target_testing():
     # Save a timestamp into list
     await _lock.acquire()
     await asyncio.sleep(_Sleep_Time)
     if (PYTHON_MAJOR_VERSION, PYTHON_MINOR_VERSION) > (3, 6):
         _async_task = asyncio.current_task(
             loop=asyncio.get_event_loop())
     else:
         _async_task = asyncio.Task.current_task()
     _async_task_id = id(_async_task)
     _time = float(time.time())
     _done_timestamp[_async_task_id] = _time
     _lock.release()
Exemple #24
0
async def shutdown():
    """
    Shutdown actions
    """
    # pylint:disable=import-outside-toplevel
    current_task = asyncio.current_task()
    other_tasks = [t for t in asyncio.all_tasks() if t is not current_task]
    LOGGER.info("Cancelling %s outstanding tasks", len(other_tasks))
    for task in other_tasks:
        task.cancel()

    await DATABASE.disconnect()
    await asyncio.gather(*other_tasks, return_exceptions=True)
Exemple #25
0
        async def finalize() -> None:
            lock = asyncio.Lock()

            async with lock:
                if self.client.is_initialized:
                    if self.stop_manual:
                        await self.client.stop(block=False)
                    else:
                        await self.client.stop()
                for task in asyncio.all_tasks():
                    if task is not asyncio.current_task():
                        task.cancel()
                await self.loop.shutdown_asyncgens()
Exemple #26
0
 async def _target_producer():
     for _ in range(3):
         await asyncio.sleep(_Sleep_Time)
         _thread_index = random.randrange(_Random_Start_Time,
                                          _Random_End_Time)
         _async_task_flag["producer"].append(_thread_index)
         if (PYTHON_MAJOR_VERSION, PYTHON_MINOR_VERSION) > (3, 6):
             _async_task_ids["producer"] = str(
                 id(asyncio.current_task()))
         else:
             _async_task_ids["producer"] = str(
                 id(asyncio.Task.current_task()))
         _lock.set()
Exemple #27
0
def check_cancelled():
    try:
        cancel_scope = _task_states[current_task()].cancel_scope
    except KeyError:
        return

    while cancel_scope:
        if cancel_scope.cancel_called:
            raise CancelledError
        elif cancel_scope.shield:
            return
        else:
            cancel_scope = cancel_scope._parent_scope
Exemple #28
0
    async def navigate(self, ctx, *, timeout=120, target=None):
        _bot = ctx.bot
        _loop = _bot.loop
        target = target or ctx.author

        if target.id in self.all_tasks:
            self.all_tasks.pop(target.id).cancel()
        self.all_tasks[target.id] = asyncio.current_task(loop=_loop)

        if ctx.channel.permissions_for(ctx.me).manage_messages:
            event = "reaction_add"
            handle_reaction = lambda m, r, u: _loop.create_task(try_it(m.remove_reaction(r, u)))
        else:
            event = "reaction_add_or_remove"
            handle_reaction = lambda m, r, u: None
        if self.first_page:
            embed = self.first_page
        elif self.container:
            embed = self.render()
        else:
            embed = next(iter(self.navigation.values()))()
        try:
            message = await ctx.send(embed=embed)
        except asyncio.CancelledError:
            return self.all_tasks.pop(target.id, None)
        if not self.navigation:
            return self.all_tasks.pop(target.id, None)
        rt = _loop.create_task(self.add_navigate_reactions(message))

        try:
            while True:
                try:
                    reaction, user = await _bot.wait_for(
                        event,
                        check=lambda r, u: target==u and r.emoji in self.navigation and r.message.id==message.id,
                        timeout=timeout
                    )
                except asyncio.TimeoutError:
                    return self.all_tasks.pop(target.id, None)
                embed = self.navigation[reaction.emoji]()
                if inspect.isawaitable(embed):
                    embed = await embed
                if embed is not None:
                    await message.edit(embed=embed)
                    handle_reaction(message, reaction, user)
                else:
                    return self.all_tasks.pop(target.id, None)
        except asyncio.CancelledError:
            rt.cancel()
        finally:
            _loop.create_task(try_it(message.clear_reactions()))
Exemple #29
0
    async def _stream_and_cache(self):
        """Stream data from upstream and cache them.

        The download and caching is done in the background, to prevent
        disconnecting clients from stopping it.
        """
        client_session = aiotask_context.get('client_session')
        self.log.info('Caching upstream', url=self.url, path=self.path)

        queue = asyncio.Queue()
        fut_finished = asyncio.Future()
        cur_task = asyncio.current_task()

        async def _stream_queue():
            while queue.qsize() or not fut_finished.done():
                data = await queue.get()
                try:
                    yield data
                finally:
                    queue.task_done()

        async def _enqueue_upstream():
            try:
                log.debug('Streaming from upstream into file and queue',
                          file=self.path_preparing,
                          url=self.url)
                async with aiofiles.open(self.path_preparing, 'xb') as f:
                    async with client_session.get(self.url) as r:
                        async for data, _ in r.content.iter_chunks():
                            await f.write(data)
                            await queue.put(data)
                        fut_finished.set_result(True)
                self.path_preparing.rename(self.path)
                self.log.info('Finished download', path=self.path)
            except (asyncio.CancelledError, IOError,
                    Exception) as ex:  # noqa: W0703
                cur_task.cancel()
                # cleanup broken download
                self.log.error('Cleaning broken download',
                               path=self.path_preparing,
                               error=ex)
                try:
                    self.path_preparing.unlink()
                except FileNotFoundError:
                    pass

        # TODO use aiojobs ??? to cancel this future graceully
        # GeneratorExit
        asyncio.ensure_future(_enqueue_upstream())
        async for data in _stream_queue():
            yield data
Exemple #30
0
    async def cancel(self):
        if not self._cancel_called:
            self._cancel_called = True

            # Check if the host task should be cancelled
            if self._host_task is not current_task():
                scope = get_cancel_scope(self._host_task)
                while scope and scope is not self:
                    if scope.shield:
                        break
                    else:
                        scope = scope._parent_scope
                else:
                    self._host_task.cancel()
Exemple #31
0
async def shutdown(signal, loop, board):
    # Shutdown teh telemtrix board
    await board.shutdown()

    # Stop the asyncio loop
    loop.stop()

    # Shutdown all tasks
    tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]
    [task.cancel() for task in tasks]
    await asyncio.gather(*tasks, return_exceptions=True)

    # Exit
    exit(0)
Exemple #32
0
    async def shutdown(self, signal=None):
        """Cleanup tasks tied to the service's shutdown."""
        if signal:
            logger.info(f"Received exit signal {signal.name}...")

        tasks = [
            t for t in asyncio.all_tasks() if t is not asyncio.current_task()
        ]

        [task.cancel() for task in tasks]

        logger.info(f"Cancelling {len(tasks)} outstanding tasks")
        await asyncio.gather(*tasks, return_exceptions=True)
        self.loop.stop()
Exemple #33
0
    async def _shutdown(self, loop: asyncio.AbstractEventLoop, signal=None) -> None:
        if not self.running:
            raise RuntimeError("Cannot shutdown an assembly that is not running")

        if signal:
            self.logger.info(f"Received exit signal {signal.name}...")

        reason = signal.name if signal else "shutdown"

        # Shut down the servo runners, breaking active control loops
        if len(self.runners) == 1:
            self.logger.info(f"Shutting down servo...")
        else:
            self.logger.info(f"Shutting down {len(self.runners)} running servos...")
        for fut in asyncio.as_completed(
            list(map(lambda r: r.shutdown(reason=reason), self.runners)), timeout=30.0
        ):
            try:
                await fut
            except Exception as error:
                self.logger.critical(
                    f"Failed servo runner shutdown with error: {error}"
                )

        # Shutdown the assembly and the servos it contains
        self.logger.debug("Dispatching shutdown event...")
        try:
            await self.assembly.shutdown()
        except Exception as error:
            self.logger.critical(f"Failed assembly shutdown with error: {error}")

        await asyncio.gather(self.progress_handler.shutdown(), return_exceptions=True)
        self.logger.remove(self.progress_handler_id)

        # Cancel any outstanding tasks -- under a clean, graceful shutdown this list will be empty
        # The shutdown of the assembly and the servo should clean up its tasks
        tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]
        if len(tasks):
            [task.cancel() for task in tasks]

            self.logger.info(f"Cancelling {len(tasks)} outstanding tasks")
            self.logger.debug(f"Outstanding tasks: {devtools.pformat(tasks)}")
            await asyncio.gather(*tasks, return_exceptions=True)

        self.logger.info("Servo shutdown complete.")
        await asyncio.gather(self.logger.complete(), return_exceptions=True)

        self._running = False

        loop.stop()
async def shutdown(loop, signal=None, log=None):
    if signal and log:
        msg = f'{datetime.now()} Received exit signal {signal.name}...'
        log.warning(msg)

    tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]

    for task in tasks:
        msg = f'{datetime.now()} Cancelling task {task.get_name()}...'
        logging.warning(msg)
        task.cancel()

    await asyncio.gather(*tasks, return_exceptions=True)
    loop.stop()
Exemple #35
0
    def __enter__(self) -> BaseTimerContext:
        task = asyncio.current_task(loop=self._loop)

        if task is None:
            raise RuntimeError(
                "Timeout context manager should be used " "inside a task"
            )

        if self._cancelled:
            task.cancel()
            raise asyncio.TimeoutError from None

        self._tasks.append(task)
        return self
Exemple #36
0
def current_task(loop=None):
    if loop is None:
        loop = asyncio.get_event_loop()

    if PY_37:
        task = asyncio.current_task(loop=loop)
    else:
        task = asyncio.Task.current_task(loop=loop)
    if task is None:
        # this should be removed, tokio must use register_task and family API
        if hasattr(loop, 'current_task'):
            task = loop.current_task()

    return task
Exemple #37
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        try:
            self.task = task = asyncio.current_task()
        except RuntimeError:
            self.task = task = None

        if task:
            self.taskName = task.get_name()
            origin = f"[{self.threadName}::{self.taskName}] {self.name}"
        else:
            self.taskName = None
            origin = f"[{self.threadName}] {self.name}"
        self.origin = TruncateAfterMaxWidthString(origin)
Exemple #38
0
    def _release(self, lock_type: int) -> None:
        # assert lock_type in (self._RL, self._WL)
        me = asyncio.current_task(loop=self._loop)
        assert me is not None  # nosec

        try:
            self._owning.remove((me, lock_type))
        except ValueError:
            raise RuntimeError('Cannot release an un-acquired lock')
        if lock_type == self._RL:
            self._r_state -= 1
        else:
            self._w_state -= 1
        self._wake_up()
Exemple #39
0
def _taskdict(task):
    '''
    Note: No locking is provided.  Under normal circumstances, like the other task is not running (e.g. this is running
    from the same event loop as the task) or task is the current task, this is fine.
    '''
    if task is None:
        task = asyncio.current_task()

    assert task
    taskvars = getattr(task, '_syn_taskvars', None)

    if taskvars is None:
        taskvars = varinit(task)

    return taskvars
Exemple #40
0
    async def promote(self, name, user, info=None):
        '''
        Promote the currently running task.
        '''
        task = asyncio.current_task()

        synt = getattr(task, '_syn_task', None)

        if synt is not None:

            if synt.root is None:
                return synt

            synt.root.kids.pop(synt.iden)
            synt.root = None
            return synt

        return await s_task.Task.anit(self, task, name, user, info=info)
Exemple #41
0
    def _loop_monitor_thread(self):
        """
        Thread responsible for checking current tasks that are taking too long
        to finish and printing the stack.

        DISCLAIMER/TODO: This is not free of race condition so it may show
        false positives.
        """
        set_thread_name('loop_monitor')
        last = None
        while True:
            time.sleep(2)
            current = asyncio.current_task(loop=self.__loop)
            if current is None:
                last = None
                continue
            if last == current:
                frame = sys._current_frames()[self.__thread_id]
                stack = traceback.format_stack(frame, limit=-10)
                self.logger.warn(''.join(['Task seems blocked:\n'] + stack))
            last = current
Exemple #42
0
    def schedCoro(self, coro):
        '''
        Schedules a free-running coroutine to run on this base's event loop.  Kills the coroutine if Base is fini'd.
        It does not pend on coroutine completion.

        Precondition:
            This function is *not* threadsafe and must be run on the Base's event loop

        Returns:
            asyncio.Task: An asyncio.Task object.

        '''
        import synapse.lib.provenance as s_provenance  # avoid import cycle

        if __debug__:
            assert s_coro.iscoro(coro)
            import synapse.lib.threads as s_threads  # avoid import cycle
            assert s_threads.iden() == self.tid

        task = self.loop.create_task(coro)

        # In rare cases, (Like this function being triggered from call_soon_threadsafe), there's no task context
        if asyncio.current_task():
            s_provenance.dupstack(task)

        def taskDone(task):
            self._active_tasks.remove(task)
            try:
                task.result()
            except asyncio.CancelledError:
                pass
            except Exception:
                logger.exception('Task scheduled through Base.schedCoro raised exception')

        self._active_tasks.add(task)
        task.add_done_callback(taskDone)

        return task
Exemple #43
0
def current():
    '''
    Return the current synapse task.
    '''
    task = asyncio.current_task()
    return getattr(task, '_syn_task', None)
Exemple #44
0
def current_task(loop: Optional[asyncio.AbstractEventLoop]=None) -> asyncio.Task:  # type: ignore  # noqa  # Return type is intentionly Generic here
    if PY_37:
        return asyncio.current_task(loop=loop)  # type: ignore
    else:
        return asyncio.Task.current_task(loop=loop)  # type: ignore
Exemple #45
0
def _is_current_task():  # pragma: no cover
    import asyncio
    if sys.version_info >= (3, 7):
        return asyncio.current_task() is not None

    return asyncio.Task.current_task() is not None
Exemple #46
0
def current_task(loop=None):
    if PY_37:
        return asyncio.current_task(loop=loop)
    else:
        return asyncio.Task.current_task(loop=loop)
Exemple #47
0
    async def async_handle(self):
        """Handle a websocket response."""
        request = self.request
        wsock = self.wsock = web.WebSocketResponse(heartbeat=55)
        await wsock.prepare(request)
        self._logger.debug("Connected")

        # Py3.7+
        if hasattr(asyncio, 'current_task'):
            # pylint: disable=no-member
            self._handle_task = asyncio.current_task()
        else:
            self._handle_task = asyncio.Task.current_task(loop=self.hass.loop)

        @callback
        def handle_hass_stop(event):
            """Cancel this connection."""
            self._cancel()

        unsub_stop = self.hass.bus.async_listen(
            EVENT_HOMEASSISTANT_STOP, handle_hass_stop)

        self._writer_task = self.hass.async_create_task(self._writer())

        auth = AuthPhase(self._logger, self.hass, self._send_message, request)
        connection = None
        disconnect_warn = None

        try:
            self._send_message(auth_required_message())

            # Auth Phase
            try:
                with async_timeout.timeout(10):
                    msg = await wsock.receive()
            except asyncio.TimeoutError:
                disconnect_warn = \
                    'Did not receive auth message within 10 seconds'
                raise Disconnect

            if msg.type in (WSMsgType.CLOSE, WSMsgType.CLOSING):
                raise Disconnect

            elif msg.type != WSMsgType.TEXT:
                disconnect_warn = 'Received non-Text message.'
                raise Disconnect

            try:
                msg = msg.json()
            except ValueError:
                disconnect_warn = 'Received invalid JSON.'
                raise Disconnect

            self._logger.debug("Received %s", msg)
            connection = await auth.async_handle(msg)

            # Command phase
            while not wsock.closed:
                msg = await wsock.receive()

                if msg.type in (WSMsgType.CLOSE, WSMsgType.CLOSING):
                    break

                elif msg.type != WSMsgType.TEXT:
                    disconnect_warn = 'Received non-Text message.'
                    break

                try:
                    msg = msg.json()
                except ValueError:
                    disconnect_warn = 'Received invalid JSON.'
                    break

                self._logger.debug("Received %s", msg)
                connection.async_handle(msg)

        except asyncio.CancelledError:
            self._logger.info("Connection closed by client")

        except Disconnect:
            pass

        except Exception:  # pylint: disable=broad-except
            self._logger.exception("Unexpected error inside websocket API")

        finally:
            unsub_stop()

            if connection is not None:
                connection.async_close()

            try:
                self._to_write.put_nowait(None)
                # Make sure all error messages are written before closing
                await self._writer_task
            except asyncio.QueueFull:
                self._writer_task.cancel()

            await wsock.close()

            if disconnect_warn is None:
                self._logger.debug("Disconnected")
            else:
                self._logger.warning("Disconnected: %s", disconnect_warn)

        return wsock
Exemple #48
0
 def current_asyncio_task(loop):
     return asyncio.current_task(loop)