示例#1
0
文件: _spawn.py 项目: smurfix/util-py
 async def _run(proc, args, kw, *, task_status):
     """
     Helper for starting a task within a cancel scope.
     """
     with anyio.CancelScope() as sc:
         task_status.started(sc)
         await proc(*args, **kw)
示例#2
0
    async def _run_reconnected(self, val: ValueEvent):
        try:
            with anyio.CancelScope() as scope:
                self._current_run = scope
                while True:
                    try:
                        await self._run_one(val)
                    except anyio.get_cancelled_exc_class():
                        raise
                    except (
                            BrokenPipeError,
                            TimeoutError,
                            EnvironmentError,
                            anyio.IncompleteRead,
                            ConnectionResetError,
                            anyio.ClosedResourceError,
                            StopAsyncIteration,
                    ) as exc:
                        if val is not None and not val.is_set():
                            val.set_error(exc)
                            return
                        logger.error("Disconnected")
                        val = None

                        await anyio.sleep(self._backoff)
                        if self._backoff < 10:
                            self._backoff *= 1.5
                    else:
                        pass
        finally:
            self._current_run = None
示例#3
0
 async def serve(self) -> None:
     await self._master.register_service(self.service_name)
     try:
         await anyio.sleep_forever()
     except anyio.get_cancelled_exc_class():
         with anyio.CancelScope(shield=True), anyio.move_on_after(1):
             await self._master.unregister_service(self.service_name)
         raise
示例#4
0
    async def aclose(self) -> None:
        # TODO mutex
        if self._instances == 1:
            self._instances -= 1
            with anyio.CancelScope(shield=True), anyio.move_on_after(1):
                await self._master.unregister_publisher(self.topic_name)

            for subscriber in self._subscribers:
                await subscriber.stream.aclose()
            self._subscribers.clear()
示例#5
0
 async def _add_task(self, val, proc, *args):
     with anyio.CancelScope() as scope:
         val.set(scope)
         try:
             await proc(*args)
         finally:
             try:
                 self._tasks.remove(scope)
             except KeyError:
                 pass
示例#6
0
 async def register(
     self,
     send_stream: MemoryObjectSendStream[abc.MessageT],
 ) -> None:
     async with self.lock:
         if not self.registered:
             with anyio.CancelScope(shield=True), anyio.move_on_after(1):
                 publisher_uris = await self.master.register_subscriber(
                     self.topic_name, getattr(self.topic_type, "_type"))
             self.registered = True
             self.update_publishers(publisher_uris)
         self.subscriptions.add(send_stream)
示例#7
0
    async def is_disconnected(self) -> bool:
        if not self._is_disconnected:
            message: Message = {}

            # If message isn't immediately available, move on
            with anyio.CancelScope() as cs:
                cs.cancel()
                message = await self._receive()

            if message.get("type") == "http.disconnect":
                self._is_disconnected = True

        return self._is_disconnected
示例#8
0
    async def _writer(self, evt):
        with anyio.CancelScope() as scope:
            self._write_task = scope
            evt.set()
            while True:
                try:
                    with anyio.fail_after(10):
                        msg = await self._wqueue_r.receive()
                except TimeoutError:
                    msg = NOPMsg()

                self.requests.append(msg)
                await msg.write(self._msg_proto)
示例#9
0
    async def _run_one(self, val: ValueEvent):
        try:
            async with anyio.create_task_group() as tg:
                self._current_tg = tg
                self.stream = await anyio.connect_tcp(self.host, self.port)

                ml, self.requests = deque(self.requests), deque()
                try:
                    self._msg_proto = MessageProtocol(self, is_server=False)

                    e_w = anyio.Event()
                    e_r = anyio.Event()
                    tg.spawn(self._writer, e_w)
                    tg.spawn(self._reader, e_r)
                    await e_r.wait()
                    await e_w.wait()

                    # re-send messages, but skip those that have been cancelled
                    while ml:
                        msg = ml.popleft()
                        if not msg.cancelled:
                            try:
                                await self._wqueue_w.send(msg)
                            except BaseException:
                                ml.appendleft(msg)

                except BaseException:
                    self.requests = ml
                    raise

                await self.chat(NOPMsg())

                if self._scan_args is not None:
                    tg.spawn(partial(self.start_scan, **self._scan_args))
                if val is not None:
                    val.set(None)
                self._backoff = 0.1
                pass  # wait for tasks
            pass  # exited tasks

        finally:
            self._current_tg = None
            if self.stream is not None:
                with anyio.CancelScope(shield=True):
                    await self.stream.aclose()
                self.stream = None
示例#10
0
 async def _reader(self, evt):
     try:
         with anyio.CancelScope() as scope:
             self._read_task = scope
             evt.set()
             it = self._msg_proto.__aiter__()
             while True:
                 try:
                     with anyio.fail_after(15):
                         res, data = await it.__anext__()
                 except StopAsyncIteration:
                     raise anyio.ClosedResourceError from None
                 except ServerBusy:
                     logger.debug("Server %s busy", self.host)
                 else:
                     msg = self.requests.popleft()
                     await msg.process_reply(res, data, self)
                     if not msg.done():
                         self.requests.appendleft(msg)
     except anyio.ClosedResourceError:
         if self._current_tg is not None:
             self._current_tg.cancel_scope.cancel()
示例#11
0
async def server(  # pylint: disable=dangerous-default-value  # intentional
        tree={},
        options={},
        events=None,
        polling=False,
        scan=None,
        initial_scan=True,
        **kw):
    """
    This is a mock 1wire server+client.

    The context manager returns the client.

    ``tree`` and ``opotions`` are used as in `some_server`, ``polling``,
    ``scan`` and ``initial_scan`` are used to set up the client, other
    keyword arguments are forwarded to the client constructor.
    """
    PORT = (os.getpid() % 9999) + 40000
    async with OWFS(**kw) as ow:
        async with anyio.create_task_group() as tg:
            s = None
            try:
                listener = await anyio.create_tcp_listener(
                    local_host="127.0.0.1", local_port=PORT, reuse_port=True)

                async def may_close():
                    try:
                        await listener.serve(
                            partial(some_server, tree, options))
                    except (anyio.ClosedResourceError,
                            anyio.BrokenResourceError):
                        pass
                    except trio.MultiError as exc:
                        exc = exc.filter(
                            lambda x: None
                            if isinstance(x, trio.Cancelled) else x, exc)
                        if not isinstance(exc, (anyio.ClosedResourceError,
                                                anyio.BrokenResourceError)):
                            raise
                    except BaseException as exc:
                        import pdb
                        pdb.set_trace()
                        raise

                if events is not None:
                    evt = anyio.Event()
                    tg.spawn(events, ow, evt)
                    await evt.wait()
                addr = listener.extra(
                    anyio.abc.SocketAttribute.raw_socket).getsockname()
                tg.spawn(may_close)

                s = await ow.add_server(*addr,
                                        polling=polling,
                                        scan=scan,
                                        initial_scan=initial_scan)
                ow.test_server = s
                yield ow
            finally:
                ow.test_server = None
                await listener.aclose()
                with anyio.CancelScope(shield=True):
                    if s is not None:
                        await s.drop()
                    await ow.push_event(None)
                    await anyio.sleep(0.1)
                tg.cancel_scope.cancel()
示例#12
0
文件: _msg.py 项目: smurfix/util-py
 async def __aexit__(self, *tb):
     if self.path is not None:
         with anyio.CancelScope(shield=True):
             await self.stream.aclose()
示例#13
0
 async def wait_native_future() -> None:
     with anyio.CancelScope():
         loop = asyncio.get_event_loop()
         await loop.create_future()
示例#14
0
 async def aclose(self) -> None:
     await self._receive_stream.aclose()
     with anyio.CancelScope(shield=True), anyio.move_on_after(1):
         await self._subscription_manager.unregister(self._send_stream)