Minor non-functional changes

- fix few typos
- remove unused imports
- fix minor code-quality issues
- replace `grpclib._protocols` with `grpclib._typing`
- fix boolean and None assertions in test cases
This commit is contained in:
Arun Babu Neelicattu
2020-07-07 19:06:43 +02:00
parent 586e28d2dc
commit 0f3ad25770
10 changed files with 57 additions and 61 deletions

View File

@@ -2,7 +2,6 @@ from abc import ABC
import asyncio
import grpclib.const
from typing import (
Any,
AsyncIterable,
AsyncIterator,
Collection,
@@ -17,8 +16,8 @@ from typing import (
from .._types import ST, T
if TYPE_CHECKING:
from grpclib._protocols import IProtoMessage
from grpclib.client import Channel, Stream
from grpclib._typing import IProtoMessage
from grpclib.client import Channel
from grpclib.metadata import Deadline

View File

@@ -21,7 +21,7 @@ class ChannelClosed(Exception):
class ChannelDone(Exception):
"""
An exception raised on an attempt to send recieve from a channel that is both closed
An exception raised on an attempt to send receive from a channel that is both closed
and empty.
"""
@@ -32,41 +32,41 @@ class AsyncChannel(AsyncIterable[T]):
"""
A buffered async channel for sending items between coroutines with FIFO ordering.
This makes decoupled bidirection steaming gRPC requests easy if used like:
This makes decoupled bidirectional steaming gRPC requests easy if used like:
.. code-block:: python
client = GeneratedStub(grpclib_chan)
request_chan = await AsyncChannel()
request_channel = await AsyncChannel()
# We can start be sending all the requests we already have
await request_chan.send_from([ReqestObject(...), ReqestObject(...)])
async for response in client.rpc_call(request_chan):
await request_channel.send_from([RequestObject(...), RequestObject(...)])
async for response in client.rpc_call(request_channel):
# The response iterator will remain active until the connection is closed
...
# More items can be sent at any time
await request_chan.send(ReqestObject(...))
await request_channel.send(RequestObject(...))
...
# The channel must be closed to complete the gRPC connection
request_chan.close()
request_channel.close()
Items can be sent through the channel by either:
- providing an iterable to the send_from method
- passing them to the send method one at a time
Items can be recieved from the channel by either:
Items can be received from the channel by either:
- iterating over the channel with a for loop to get all items
- calling the recieve method to get one item at a time
- calling the receive method to get one item at a time
If the channel is empty then recievers will wait until either an item appears or the
If the channel is empty then receivers will wait until either an item appears or the
channel is closed.
Once the channel is closed then subsequent attempt to send through the channel will
fail with a ChannelClosed exception.
When th channel is closed and empty then it is done, and further attempts to recieve
When th channel is closed and empty then it is done, and further attempts to receive
from it will fail with a ChannelDone exception
If multiple coroutines recieve from the channel concurrently, each item sent will be
recieved by only one of the recievers.
If multiple coroutines receive from the channel concurrently, each item sent will be
received by only one of the receivers.
:param source:
An optional iterable will items that should be sent through the channel
@@ -74,7 +74,7 @@ class AsyncChannel(AsyncIterable[T]):
:param buffer_limit:
Limit the number of items that can be buffered in the channel, A value less than
1 implies no limit. If the channel is full then attempts to send more items will
result in the sender waiting until an item is recieved from the channel.
result in the sender waiting until an item is received from the channel.
:param close:
If set to True then the channel will automatically close after exhausting source
or immediately if no source is provided.
@@ -85,7 +85,7 @@ class AsyncChannel(AsyncIterable[T]):
):
self._queue: asyncio.Queue[Union[T, object]] = asyncio.Queue(buffer_limit)
self._closed = False
self._waiting_recievers: int = 0
self._waiting_receivers: int = 0
# Track whether flush has been invoked so it can only happen once
self._flushed = False
@@ -95,14 +95,14 @@ class AsyncChannel(AsyncIterable[T]):
async def __anext__(self) -> T:
if self.done():
raise StopAsyncIteration
self._waiting_recievers += 1
self._waiting_receivers += 1
try:
result = await self._queue.get()
if result is self.__flush:
raise StopAsyncIteration
return result
finally:
self._waiting_recievers -= 1
self._waiting_receivers -= 1
self._queue.task_done()
def closed(self) -> bool:
@@ -116,12 +116,12 @@ class AsyncChannel(AsyncIterable[T]):
Check if this channel is done.
:return: True if this channel is closed and and has been drained of items in
which case any further attempts to recieve an item from this channel will raise
which case any further attempts to receive an item from this channel will raise
a ChannelDone exception.
"""
# After close the channel is not yet done until there is at least one waiting
# reciever per enqueued item.
return self._closed and self._queue.qsize() <= self._waiting_recievers
# receiver per enqueued item.
return self._closed and self._queue.qsize() <= self._waiting_receivers
async def send_from(
self, source: Union[Iterable[T], AsyncIterable[T]], close: bool = False
@@ -158,22 +158,22 @@ class AsyncChannel(AsyncIterable[T]):
await self._queue.put(item)
return self
async def recieve(self) -> Optional[T]:
async def receive(self) -> Optional[T]:
"""
Returns the next item from this channel when it becomes available,
or None if the channel is closed before another item is sent.
:return: An item from the channel
"""
if self.done():
raise ChannelDone("Cannot recieve from a closed channel")
self._waiting_recievers += 1
raise ChannelDone("Cannot receive from a closed channel")
self._waiting_receivers += 1
try:
result = await self._queue.get()
if result is self.__flush:
return None
return result
finally:
self._waiting_recievers -= 1
self._waiting_receivers -= 1
self._queue.task_done()
def close(self):
@@ -190,8 +190,8 @@ class AsyncChannel(AsyncIterable[T]):
"""
if not self._flushed:
self._flushed = True
deadlocked_recievers = max(0, self._waiting_recievers - self._queue.qsize())
for _ in range(deadlocked_recievers):
deadlocked_receivers = max(0, self._waiting_receivers - self._queue.qsize())
for _ in range(deadlocked_receivers):
await self._queue.put(self.__flush)
# A special signal object for flushing the queue when the channel is closed