File tree Expand file tree Collapse file tree 3 files changed +32
-6
lines changed
src/frequenz/channels/experimental Expand file tree Collapse file tree 3 files changed +32
-6
lines changed Original file line number Diff line number Diff line change 1414
1515## Bug Fixes
1616
17- <!-- Here goes notable bug fixes that are worth a special mention or explanation -->
17+ - Fix ` NopReceiver.ready() ` to properly terminate when receiver is closed.
Original file line number Diff line number Diff line change @@ -20,7 +20,7 @@ class NopReceiver(Receiver[ReceiverMessageT_co]):
2020
2121 def __init__ (self ) -> None :
2222 """Initialize this instance."""
23- self ._closed : bool = False
23+ self ._ready_future : asyncio . Future [ bool ] = asyncio . Future ()
2424
2525 @override
2626 async def ready (self ) -> bool :
@@ -29,9 +29,9 @@ async def ready(self) -> bool:
2929 Returns:
3030 Whether the receiver is still active.
3131 """
32- if self ._closed :
32+ if self ._ready_future . done () :
3333 return False
34- await asyncio . Future ()
34+ await self . _ready_future
3535 return False
3636
3737 @override
@@ -47,11 +47,12 @@ def consume(self) -> ReceiverMessageT_co: # noqa: DOC503 (raised indirectly)
4747 ReceiverStoppedError: If the receiver stopped producing messages.
4848 ReceiverError: If there is some problem with the underlying receiver.
4949 """
50- if self ._closed :
50+ if self ._ready_future . done () :
5151 raise ReceiverStoppedError (self )
5252 raise ReceiverError ("`consume()` must be preceded by a call to `ready()`" , self )
5353
5454 @override
5555 def close (self ) -> None :
5656 """Stop the receiver."""
57- self ._closed = True
57+ if not self ._ready_future .done ():
58+ self ._ready_future .set_result (False )
Original file line number Diff line number Diff line change @@ -38,3 +38,28 @@ async def test_consuming_raises() -> None:
3838 receiver .close ()
3939 with pytest .raises (ReceiverStoppedError ):
4040 receiver .consume ()
41+
42+
43+ async def test_close_method_effect_on_ready () -> None :
44+ """Test `ready()` terminates when the receiver is closed.
45+
46+ When the receiver is closed, `ready()` should return False.
47+ This test verifies that:
48+ 1. `ready()` returns False immediately after `close()` is called
49+ 2. `ready()` and `close()` can be called multiple times
50+ """
51+ receiver = NopReceiver [int ]()
52+
53+ # Create a task that waits for the receiver to be ready.
54+ task = asyncio .create_task (receiver .ready ())
55+
56+ # Wait for the task to start.
57+ await asyncio .sleep (0.1 )
58+
59+ # Close the receiver and wait for the task to complete.
60+ receiver .close ()
61+ assert await asyncio .wait_for (task , timeout = 0.1 ) is False
62+
63+ # Second call to `close()` or `ready()` should not raise an error.
64+ receiver .close ()
65+ assert await asyncio .wait_for (receiver .ready (), timeout = 0.1 ) is False
You can’t perform that action at this time.
0 commit comments