Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ body:
- Documentation (part:docs)
- Unit, integration and performance tests (part:tests)
- Build script, CI, dependencies, etc. (part:tooling)
- Channels, `Broadcast`, `Bidirectional`, etc. (part:channels)
- Channels, `Broadcast`, `Anycast`, etc. (part:channels)
- Select (part:select)
- Utility receivers, `Merge`, etc. (part:receivers)
validations:
Expand Down
17 changes: 9 additions & 8 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# For more details on the configuration please see:
# https://github.com/marketplace/actions/labeler

"part:docs":
"part:docs":
- "**/*.md"
- "docs/**"
- "examples/**"
Expand All @@ -31,14 +31,15 @@
- noxfile.py

"part:channels":
- any:
- "src/frequenz/channels/**"
- "!src/frequenz/channels/util/**"
- "src/frequenz/channels/_anycast.py"
- "src/frequenz/channels/_broadcast.py"

"part:receivers":
- any:
- "src/frequenz/channels/util/**"
- "!src/frequenz/channels/util/_select.py"
- "src/frequenz/channels/_merge.py"
- "src/frequenz/channels/_merge_named.py"
- "src/frequenz/channels/event.py"
- "src/frequenz/channels/file_watcher.py"
- "src/frequenz/channels/timer.py"

"part:select":
- "src/frequenz/channels/util/_select.py"
- "src/frequenz/channels/_select.py"
62 changes: 57 additions & 5 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

## Summary

The `Timer` now can be started with a delay.

## Upgrading

Expand All @@ -12,11 +11,9 @@ The `Timer` now can be started with a delay.

You should instantiate using `Anycast(name=..., limit=...)` (or `Anycast(name=...)` if the default `limit` is enough) instead of `Anycast(...)` or `Anycast(maxsize=...)`.

* `Bidirectional`

- The `client_id` and `service_id` arguments were merged into a keyword-only `name`.
- `new_sender` and `new_receiver`: They now return a base `Sender` and `Receiver` class (respectively) instead of a channel-specific `Sender` or `Receiver` subclass.

You should instantiate using `Bidirectional(name=...)` instead of `Bidirectional(..., ...)` or `Bidirectional(client_id=..., service_id=...)`.
This means users now don't have access to the internals to the channel-specific `Sender` and `Receiver` subclasses.

* `Broadcast`

Expand All @@ -28,16 +25,71 @@ The `Timer` now can be started with a delay.

You should use `.new_receiver(name=name, limit=limit)` (or `.new_receiver()` if the defaults are enough) instead of `.new_receiver(name)` or `.new_receiver(name, maxsize)`.

- `new_sender` and `new_receiver` now return a base `Sender` and `Receiver` class (respectively) instead of a channel-specific `Sender` or `Receiver` subclass.

This means users now don't have access to the internals to the channel-specific `Sender` and `Receiver` subclasses.

* `Event`

- `__init__`: The `name` argument was made keyword-only. The default was changed to a more readable version of `id(self)`.

You should instantiate using `Event(name=...)` instead of `Event(...)`.

- Moved from `frequenz.channels.util` to `frequenz.channels.event`.

* `FileWatcher`

- Moved from `frequenz.channels.util` to `frequenz.channels.file_watcher`.

- Support classes are no longer nested inside `FileWatcher`. They are now top-level classes within the new `frequenz.channels.file_watcher` module (e.g., `frequenz.channels.util.FileWatcher.EventType` -> `frequenz.channels.file_watcher.EventType`, `frequenz.channels.util.FileWatcher.Event` -> `frequenz.channels.file_watcher.Event`).

* `Timer` and support classes

- Moved from `frequenz.channels.util` to `frequenz.channels.timer`.

* All exceptions that took `Any` as the `message` argument now take `str` instead.

If you were passing a non-`str` value to an exception, you should convert it using `str(value)` before passing it to the exception.

* The following symbols were moved to the top-level `frequenz.channels` package:

- `Merge`
- `MergeNamed`
- `Selected`
- `SelectError`
- `SelectErrorGroup`
- `UnhandledSelectedError`
- `select`
- `selected_from`

### Removals

* `Bidirectional`

This channel was removed as it is not recommended practice and was a niche use case. If you need to use it, you can set up two channels or copy the `Bidirectional` class from the previous version to your project.

* `Peekable`

This class was removed because it was merely a shortcut to a receiver that caches the last value received. It did not fit the channel abstraction well and was infrequently used.

You can replace it with a task that receives and retains the last value.

* `Broadcast.new_peekable()`

This was removed alongside `Peekable`.

* `Receiver.into_peekable()`

This was removed alongside `Peekable`.

* `ReceiverInvalidatedError`

This was removed alongside `Peekable` (it was only raised when using a `Receiver` that was converted into a `Peekable`).

* `util`

The entire `util` package was removed and its symbols were either moved to the top-level package or to their own public modules (as noted above).

## New Features

* `Anycast`
Expand Down
89 changes: 54 additions & 35 deletions src/frequenz/channels/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,32 @@
This package contains
[channel](https://en.wikipedia.org/wiki/Channel_(programming)) implementations.

Base classes:

* [Receiver][frequenz.channels.Receiver]: An object that can wait for and
consume messages from a channel.

* [Sender][frequenz.channels.Sender]: An object that can send messages to
a channel.

Channels:

* [Anycast][frequenz.channels.Anycast]: A channel that supports multiple
senders and multiple receivers. A message sent through a sender will be
received by exactly one receiver.

* [Bidirectional][frequenz.channels.Bidirectional]: A channel providing
a `client` and a `service` handle to send and receive bidirectionally.

* [Broadcast][frequenz.channels.Broadcast]: A channel to broadcast messages
from multiple senders to multiple receivers. Each message sent through any of
the senders is received by all of the receivers.

Other base classes:
Utilities to work with channels:

* [Peekable][frequenz.channels.Peekable]: An object to allow users to get
a peek at the latest value in the channel, without consuming anything.
* [Merge][frequenz.channels.Merge] and [MergeNamed][frequenz.channels.MergeNamed]:
[Receivers][frequenz.channels.Receiver] that merge messages coming from multiple
receivers into a single stream.

* [Receiver][frequenz.channels.Receiver]: An object that can wait for and
consume messages from a channel.

* [Sender][frequenz.channels.Sender]: An object that can send messages to
a channel.

Utilities:

* [util][frequenz.channels.util]: A module with utilities, like special
receivers that implement timers, file watchers, merge receivers, or wait for
messages in multiple channels.
* [select][frequenz.channels.select]: Iterate over the values of all
[receivers][frequenz.channels.Receiver] as new values become available.

Exception classes:

Expand All @@ -56,39 +53,61 @@
* [ReceiverStoppedError][frequenz.channels.ReceiverStoppedError]: A receiver
stopped producing messages.

* [ReceiverInvalidatedError][frequenz.channels.ReceiverInvalidatedError]:
A receiver is not longer valid (for example if it was converted into
a peekable.
* [SelectError][frequenz.channels.SelectError]: Base class for all errors
related to [select][frequenz.channels.select].

* [SelectErrorGroup][frequenz.channels.SelectErrorGroup]: A group of errors
raised by [select][frequenz.channels.select].

* [UnhandledSelectedError][frequenz.channels.UnhandledSelectedError]: An error
raised by [select][frequenz.channels.select] that was not handled by the
user.

Extra utility receivers:

* [Event][frequenz.channels.event.Event]: A receiver that generates a message when
an event is set.

* [FileWatcher][frequenz.channels.file_watcher.FileWatcher]: A receiver that
generates a message when a file is added, modified or deleted.

* [Timer][frequenz.channels.timer.Timer]: A receiver that generates a message after a
given amount of time.
"""

from . import util
from ._anycast import Anycast
from ._base_classes import Peekable, Receiver, Sender
from ._bidirectional import Bidirectional
from ._broadcast import Broadcast
from ._exceptions import (
ChannelClosedError,
ChannelError,
Error,
ReceiverError,
ReceiverInvalidatedError,
ReceiverStoppedError,
SenderError,
from ._exceptions import ChannelClosedError, ChannelError, Error
from ._merge import Merge
from ._merge_named import MergeNamed
from ._receiver import Receiver, ReceiverError, ReceiverStoppedError
from ._select import (
Selected,
SelectError,
SelectErrorGroup,
UnhandledSelectedError,
select,
selected_from,
)
from ._sender import Sender, SenderError

__all__ = [
"Anycast",
"Bidirectional",
"Broadcast",
"ChannelClosedError",
"ChannelError",
"Error",
"Peekable",
"Merge",
"MergeNamed",
"Receiver",
"ReceiverError",
"ReceiverInvalidatedError",
"ReceiverStoppedError",
"SelectError",
"SelectErrorGroup",
"Selected",
"Sender",
"SenderError",
"util",
"UnhandledSelectedError",
"select",
"selected_from",
]
Loading