Skip to content

Commit f7880b8

Browse files
committed
RFC: Revamp the repository modules structure
These are the most notable changes: - The `_base_classes` modules is split into the `_receiver` and `_sender` modules. - Sender and receiver exceptions are moved from the `_exceptions` module to the new `_sender` and `_receiver` modules. - The `frequenz.channel` package now only exposes the new `_receiver` and `_sender` modules, and the `_exceptions` and `_select` modules. - All channels and receiver modules are moved to the `frequenz.channels` package and made public. - All public nested classes were moved to the top level of the corresponding module. Advantages of this structure: - It completely removes circular dependencies. - It avoids importing unnecessary code. In Python importing means code execution, so even when it is done only at startup, it adds some overhead. Also by not importing unnecessary code, we can potentially add real optional dependencies. For example, if a project doesn't need to use a file watcher, they could avoid pulling the unnecessary `awatch` dependency. This is not done in this PR, but it could be done in the future. - By having the channels and receivers on their own module we can move public nested classes were moved to the top level of the corresponding module withough having to add superflous prefixes for support classes. - Removing nested classes avoids having to use hacky constructions, like requiring the use of `from __future__ import annotations`, types as strings (nested classes) and confusing the `mkdocstrings` tools when extracting and cross-linking docs. - The `frequenz.channels` package exposes all classes that are used once you have setted up your channels, so the importing should still be pretty terse in most cases and only `frequenz.channels` would need to be imported in modules only taking some receivers and iterating or selecting over them. Signed-off-by: Leandro Lucarella <[email protected]>
1 parent a698896 commit f7880b8

30 files changed

+562
-649
lines changed

.github/labeler.yml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# For more details on the configuration please see:
77
# https://github.com/marketplace/actions/labeler
88

9-
"part:docs":
9+
"part:docs":
1010
- "**/*.md"
1111
- "docs/**"
1212
- "examples/**"
@@ -31,14 +31,16 @@
3131
- noxfile.py
3232

3333
"part:channels":
34-
- any:
35-
- "src/frequenz/channels/**"
36-
- "!src/frequenz/channels/util/**"
34+
- "src/frequenz/channels/anycast.py"
35+
- "src/frequenz/channels/bidirectional.py"
36+
- "src/frequenz/channels/broadcast.py"
3737

3838
"part:receivers":
39-
- any:
40-
- "src/frequenz/channels/util/**"
41-
- "!src/frequenz/channels/util/_select.py"
39+
- "src/frequenz/channels/event.py"
40+
- "src/frequenz/channels/file_watcher.py"
41+
- "src/frequenz/channels/merge.py"
42+
- "src/frequenz/channels/merge_named.py"
43+
- "src/frequenz/channels/timer.py"
4244

4345
"part:select":
44-
- "src/frequenz/channels/util/_select.py"
46+
- "src/frequenz/channels/_select.py"

benchmarks/benchmark_anycast.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
from collections.abc import Coroutine
1010
from typing import Any
1111

12-
from frequenz.channels import Anycast, Receiver, Sender
12+
from frequenz.channels import Receiver, Sender
13+
from frequenz.channels.anycast import Anycast
1314

1415

1516
async def send_msg(num_messages: int, chan: Sender[int]) -> None:

benchmarks/benchmark_broadcast.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
from functools import partial
1111
from typing import Any
1212

13-
from frequenz.channels import Broadcast, Receiver, Sender
13+
from frequenz.channels import Receiver, Sender
14+
from frequenz.channels.broadcast import Broadcast
1415

1516

1617
async def component_sender(num_messages: int, chan: Sender[int]) -> None:

src/frequenz/channels/__init__.py

Lines changed: 33 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -6,80 +6,50 @@
66
This package contains
77
[channel](https://en.wikipedia.org/wiki/Channel_(programming)) implementations.
88
9-
Channels:
10-
11-
* [Anycast][frequenz.channels.Anycast]: A channel that supports multiple
12-
senders and multiple receivers. A message sent through a sender will be
13-
received by exactly one receiver.
14-
15-
* [Bidirectional][frequenz.channels.Bidirectional]: A channel providing
16-
a `client` and a `service` handle to send and receive bidirectionally.
17-
18-
* [Broadcast][frequenz.channels.Broadcast]: A channel to broadcast messages
19-
from multiple senders to multiple receivers. Each message sent through any of
20-
the senders is received by all of the receivers.
21-
22-
Other base classes:
23-
24-
* [Peekable][frequenz.channels.Peekable]: An object to allow users to get
25-
a peek at the latest value in the channel, without consuming anything.
26-
27-
* [Receiver][frequenz.channels.Receiver]: An object that can wait for and
28-
consume messages from a channel.
9+
Main base classes and functions:
2910
3011
* [Sender][frequenz.channels.Sender]: An object that can send messages to
3112
a channel.
3213
33-
Utilities:
34-
35-
* [util][frequenz.channels.util]: A module with utilities, like special
36-
receivers that implement timers, file watchers, merge receivers, or wait for
37-
messages in multiple channels.
38-
39-
Exception classes:
40-
41-
* [Error][frequenz.channels.Error]: Base class for all errors in this
42-
library.
43-
44-
* [ChannelError][frequenz.channels.ChannelError]: Base class for all errors
45-
related to channels.
14+
* [Receiver][frequenz.channels.Receiver]: An object that can wait for and
15+
consume messages from a channel.
4616
47-
* [ChannelClosedError][frequenz.channels.ChannelClosedError]: Error raised when
48-
trying to operate (send, receive, etc.) through a closed channel.
17+
* [selected()][frequenz.channels.select]: A function to wait on multiple
18+
receivers at once.
4919
50-
* [SenderError][frequenz.channels.SenderError]: Base class for all errors
51-
related to senders.
20+
Channels:
5221
53-
* [ReceiverError][frequenz.channels.ReceiverError]: Base class for all errors
54-
related to receivers.
22+
* [Anycast][frequenz.channels.anycast.Anycast]: A channel that supports multiple
23+
senders and multiple receivers. A message sent through a sender will be
24+
received by exactly one receiver.
5525
56-
* [ReceiverStoppedError][frequenz.channels.ReceiverStoppedError]: A receiver
57-
stopped producing messages.
26+
* [Bidirectional][frequenz.channels.bidirectional.Bidirectional]: A channel providing
27+
a `client` and a `service` handle to send and receive bidirectionally.
5828
59-
* [ReceiverInvalidatedError][frequenz.channels.ReceiverInvalidatedError]:
60-
A receiver is not longer valid (for example if it was converted into
61-
a peekable.
29+
* [Broadcast][frequenz.channels.broadcast.Broadcast]: A channel to broadcast messages
30+
from multiple senders to multiple receivers. Each message sent through any of
31+
the senders is received by all of the receivers.
6232
"""
6333

64-
from . import util
65-
from ._anycast import Anycast
66-
from ._base_classes import Peekable, Receiver, Sender
67-
from ._bidirectional import Bidirectional
68-
from ._broadcast import Broadcast
69-
from ._exceptions import (
70-
ChannelClosedError,
71-
ChannelError,
72-
Error,
34+
from ._exceptions import ChannelClosedError, ChannelError, Error
35+
from ._receiver import (
36+
Peekable,
37+
Receiver,
7338
ReceiverError,
7439
ReceiverInvalidatedError,
7540
ReceiverStoppedError,
76-
SenderError,
7741
)
42+
from ._select import (
43+
Selected,
44+
SelectError,
45+
SelectErrorGroup,
46+
UnhandledSelectedError,
47+
select,
48+
selected_from,
49+
)
50+
from ._sender import Sender, SenderError
7851

7952
__all__ = [
80-
"Anycast",
81-
"Bidirectional",
82-
"Broadcast",
8353
"ChannelClosedError",
8454
"ChannelError",
8555
"Error",
@@ -88,7 +58,12 @@
8858
"ReceiverError",
8959
"ReceiverInvalidatedError",
9060
"ReceiverStoppedError",
61+
"SelectError",
62+
"SelectErrorGroup",
63+
"Selected",
9164
"Sender",
9265
"SenderError",
93-
"util",
66+
"UnhandledSelectedError",
67+
"select",
68+
"selected_from",
9469
]

src/frequenz/channels/_bidirectional.py

Lines changed: 0 additions & 205 deletions
This file was deleted.

0 commit comments

Comments
 (0)