Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _put_nowait(self, data, *, sender):
if self._queue.closed:
logger.warning("Pub/Sub listener message after stop:"
" sender: %r, data: %r",
sender, data)
return
self._queue.put((sender, data))
self._in_pubsub = data
elif kind in (b'psubscribe', b'punsubscribe'):
if process_waiters and self._in_pubsub and self._waiters:
self._process_data(obj)
if kind == b'punsubscribe':
ch = self._pubsub_patterns.pop(chan, None)
if ch:
ch.close()
self._in_pubsub = data
elif kind == b'message':
self._pubsub_channels[chan].put_nowait(data)
elif kind == b'pmessage':
pattern = pattern[0]
self._pubsub_patterns[pattern].put_nowait((chan, data))
else:
logger.warning("Unknown pubsub message received %r", obj)
When queue of free connections is full the connection will be dropped.
"""
assert conn in self._used, (
"Invalid connection, maybe from other pool", conn)
self._used.remove(conn)
if not conn.closed:
if conn.in_transaction:
logger.warning(
"Connection %r is in transaction, closing it.", conn)
conn.close()
elif conn.in_pubsub:
logger.warning(
"Connection %r is in subscribe mode, closing it.", conn)
conn.close()
elif conn._waiters:
logger.warning(
"Connection %r has pending commands, closing it.", conn)
conn.close()
elif conn.db == self.db:
if self.maxsize and self.freesize < self.maxsize:
self._pool.append(conn)
else:
# consider this connection as old and close it.
conn.close()
else:
conn.close()
# FIXME: check event loop is not closed
asyncio.ensure_future(self._wakeup())
def release(self, conn):
"""Returns used connection back into pool.
When returned connection has db index that differs from one in pool
the connection will be closed and dropped.
When queue of free connections is full the connection will be dropped.
"""
assert conn in self._used, (
"Invalid connection, maybe from other pool", conn)
self._used.remove(conn)
if not conn.closed:
if conn.in_transaction:
logger.warning(
"Connection %r is in transaction, closing it.", conn)
conn.close()
elif conn.in_pubsub:
logger.warning(
"Connection %r is in subscribe mode, closing it.", conn)
conn.close()
elif conn._waiters:
logger.warning(
"Connection %r has pending commands, closing it.", conn)
conn.close()
elif conn.db == self.db:
if self.maxsize and self.freesize < self.maxsize:
self._pool.append(conn)
else:
# consider this connection as old and close it.
conn.close()
def _set_result(fut, result, *info):
if fut.done():
logger.debug("Waiter future is already done %r %r", fut, info)
assert fut.cancelled(), (
"waiting future is in wrong state", fut, result, info)
else:
fut.set_result(result)
async def _do_close(self):
async with self._cond:
assert not self._acquiring, self._acquiring
waiters = []
while self._pool:
conn = self._pool.popleft()
conn.close()
waiters.append(conn.wait_closed())
for conn in self._used:
conn.close()
waiters.append(conn.wait_closed())
await asyncio.gather(*waiters)
# TODO: close _pubsub_conn connection
logger.debug("Closed %d connection(s)", len(waiters))
This function is a coroutine.
"""
assert isinstance(address, (tuple, list, str)), "tuple or str expected"
if isinstance(address, (list, tuple)):
host, port = address
logger.debug("Creating tcp connection to %r", address)
reader, writer = yield from asyncio.open_connection(
host, port, ssl=ssl, loop=loop)
sock = writer.transport.get_extra_info('socket')
if sock is not None:
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
address = sock.getpeername()
address = tuple(address[:2])
else:
logger.debug("Creating unix connection to %r", address)
reader, writer = yield from asyncio.open_unix_connection(
address, ssl=ssl, loop=loop)
sock = writer.transport.get_extra_info('socket')
if sock is not None:
address = sock.getpeername()
conn = RedisConnection(reader, writer, encoding=encoding,
address=address, loop=loop)
try:
if password is not None:
yield from conn.auth(password)
if db is not None:
yield from conn.select(db)
except Exception as err:
conn.close()
yield from conn.wait_closed()
self._closing = False
self._writer.transport.close()
self._reader_task.cancel()
self._reader_task = None
self._writer = None
self._reader = None
while self._waiters:
waiter, *spam = self._waiters.popleft()
logger.debug("Cancelling waiter %r", (waiter, spam))
if exc is None:
waiter.cancel()
else:
waiter.set_exception(exc)
while self._pubsub_channels:
_, ch = self._pubsub_channels.popitem()
logger.debug("Closing pubsub channel %r", ch)
ch.close()
while self._pubsub_patterns:
_, ch = self._pubsub_patterns.popitem()
logger.debug("Closing pubsub pattern %r", ch)
ch.close()
def _read_data(self):
"""Response reader task."""
while not self._reader.at_eof():
try:
data = yield from self._reader.read(MAX_CHUNK_SIZE)
except asyncio.CancelledError:
break
except Exception as exc:
# XXX: for QUIT command connection error can be received
# before response
logger.error("Exception on data read %r", exc, exc_info=True)
break
self._parser.feed(data)
while True:
try:
obj = self._parser.gets()
except ProtocolError as exc:
# ProtocolError is fatal
# so connection must be closed
self._closing = True
self._loop.call_soon(self._do_close, exc)
if self._in_transaction is not None:
self._transaction_error = exc
return
else:
if obj is False:
break
def _set_exception(fut, exception):
if fut.done():
logger.debug("Waiter future is already done %r", fut)
assert fut.cancelled(), (
"waiting future is in wrong state", fut, exception)
else:
fut.set_exception(exception)