1616from ._exceptions import ChannelClosedError
1717from ._generic import ChannelMessageT
1818from ._receiver import Receiver , ReceiverStoppedError
19- from ._sender import Sender , SenderError
19+ from ._sender import Sender , SenderClosedError , SenderError
2020
2121_logger = logging .getLogger (__name__ )
2222
@@ -334,6 +334,9 @@ def __init__(self, channel: Broadcast[_T], /) -> None:
334334 self ._channel : Broadcast [_T ] = channel
335335 """The broadcast channel this sender belongs to."""
336336
337+ self ._closed : bool = False
338+ """Whether this sender is closed."""
339+
337340 @override
338341 async def send (self , message : _T , / ) -> None :
339342 """Send a message to all broadcast receivers.
@@ -345,7 +348,10 @@ async def send(self, message: _T, /) -> None:
345348 SenderError: If the underlying channel was closed.
346349 A [ChannelClosedError][frequenz.channels.ChannelClosedError] is
347350 set as the cause.
351+ SenderClosedError: If this sender was closed.
348352 """
353+ if self ._closed :
354+ raise SenderClosedError (self )
349355 # pylint: disable=protected-access
350356 if self ._channel ._closed :
351357 raise SenderError ("The channel was closed" , self ) from ChannelClosedError (
@@ -365,6 +371,16 @@ async def send(self, message: _T, /) -> None:
365371 self ._channel ._recv_cv .notify_all ()
366372 # pylint: enable=protected-access
367373
374+ @override
375+ async def aclose (self ) -> None :
376+ """Close this sender.
377+
378+ After a sender is closed, it can no longer be used to send messages. Any
379+ attempt to send a message through a closed sender will raise a
380+ [SenderError][frequenz.channels.SenderError].
381+ """
382+ self ._closed = True
383+
368384 def __str__ (self ) -> str :
369385 """Return a string representation of this sender."""
370386 return f"{ self ._channel } :{ type (self ).__name__ } "
0 commit comments