async def _reader(self, mpsp: Receiver) -> None: reader_err: Optional[Exception] = None try: while True: _, msg = await mpsp.get() msg_str = msg.decode(self.encoding) if msg_str in self.waiters: for fut in self.waiters[msg_str]: fut.set_result(None) except Exception as err: reader_err = err app.log_err(err) while True: # сбрасываем все Future, т.к. они скорее всего не дождутся # поступления из канала, т.о. они будут # бороться за захват в реальном времени for wl in self.waiters.values(): for fut in wl: if not fut.done(): fut.set_result(NO_WAIT) try: await self._connect_subscr() reader_err = None return except Exception: await asyncio.sleep(0.1) finally: # если не удалось переподключиться, то сохраняем ошибку # из-за которой все случилось self._reader_err = reader_err
async def _exec_single(self, req: RestRpcRequest) -> Optional[rpc.RPCResponse]: try: res = await self._exec(req.method, req.kwargs, req.one_way) return req.respond(self.cast2dump(res)) except Exception as e: if not hasattr(e, 'code'): app.log_err(e) return req.error_respond(e) finally: if req.one_way: return None
async def _connect(self) -> None: for i in range(self.cfg.connect_max_attempts): app.log_info("Connecting to %s", masked_url(self.cfg.url)) try: self.pg = await asyncpg.connect(self.cfg.url) self._conn_lock = asyncio.Lock() app.log_info("Connected to %s", masked_url(self.cfg.url)) return except Exception as e: app.log_err(str(e)) await asyncio.sleep(self.cfg.connect_retry_delay) raise PrepareError("Could not connect to %s" % masked_url(self.cfg.url))