|
2 | 2 |
|
3 | 3 | ## Summary |
4 | 4 |
|
5 | | -This is the first stable release of the Frequenz channels library. |
6 | | - |
7 | | -If you are **upgrading from the previous 1.0.0 pre-releases**, please look into the release notes for those versions to see the changes and upgrade instructions: |
8 | | - |
9 | | -* [1.0.0-rc.1](https://github.com/frequenz-floss/frequenz-channels-python/releases/tag/v1.0.0-rc.1) |
10 | | -* [1.0.0-beta.2](https://github.com/frequenz-floss/frequenz-channels-python/releases/tag/v1.0.0-beta.2) |
11 | | -* [1.0.0-beta.1](https://github.com/frequenz-floss/frequenz-channels-python/releases/tag/v1.0.0-beta.1) |
12 | | - |
13 | | -There were no changes between 1.0.0-rc.1 and this 1.0.0 final release. |
14 | | - |
15 | | -If you are **upgrading from v0.16.x**, please keep reading these release notes. |
| 5 | +<!-- Here goes a general summary of what this release is about --> |
16 | 6 |
|
17 | 7 | ## Upgrading |
18 | 8 |
|
19 | | -* The following symbols were moved to the top-level `frequenz.channels` package: |
20 | | - |
21 | | - - `Selected` |
22 | | - - `SelectError` |
23 | | - - `UnhandledSelectedError` |
24 | | - - `select` |
25 | | - - `selected_from` |
26 | | - |
27 | | -* `util` |
28 | | - |
29 | | - 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). |
30 | | - |
31 | | -* All exceptions that took `Any` as the `message` argument now take `str` instead. |
32 | | - |
33 | | - If you were passing a non-`str` value to an exception, you should convert it using `str(value)` before passing it to the exception. |
34 | | - |
35 | | -* `Anycast` |
36 | | - |
37 | | - - `__init__`: The `maxsize` argument was renamed to `limit` and made keyword-only and a new keyword-only `name` (required) argument was added. |
38 | | - |
39 | | - You should instantiate using `Anycast(name=..., limit=...)` (or `Anycast(name=...)` if the default `limit` is enough) instead of `Anycast(...)` or `Anycast(maxsize=...)`. |
40 | | - |
41 | | - - The following properties were changed: |
42 | | - |
43 | | - - `limit`: is now read-only. |
44 | | - - `closed`: is now named `is_closed` and read-only. |
45 | | - |
46 | | - - `new_sender` and `new_receiver`: They now return a base `Sender` and `Receiver` class (respectively) instead of a channel-specific `Sender` or `Receiver` subclass. |
47 | | - |
48 | | - This means users now don't have access to the internals to the channel-specific `Sender` and `Receiver` subclasses. |
49 | | - |
50 | | -* `Broadcast` |
51 | | - |
52 | | - - `__init__`: The `name` and `resend_latest` arguments were made keyword-only. |
53 | | - |
54 | | - You should instantiate using `Broadcast(name=name, resend_latest=resend_latest)` (or `Broadcast()` if the defaults are enough) instead of `Broadcast(name)` or `Broadcast(name, resend_latest)`. |
55 | | - |
56 | | - - The following properties were changed: |
57 | | - |
58 | | - - `limit`: is now read-only. |
59 | | - - `closed`: is now named `is_closed` and read-only. |
60 | | - |
61 | | - - `new_receiver`: The `maxsize` argument was renamed to `limit` and made keyword-only; the `name` argument was also made keyword-only. If a `name` is not specified, it will be generated from the `id()` of the instance instead of a random UUID. |
62 | | - |
63 | | - 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)`. |
64 | | - |
65 | | - - `new_sender` and `new_receiver` now return a base `Sender` and `Receiver` class (respectively) instead of a channel-specific `Sender` or `Receiver` subclass. |
66 | | - |
67 | | - This means users now don't have access to the internals to the channel-specific `Sender` and `Receiver` subclasses. |
68 | | - |
69 | | -* `Event` |
70 | | - |
71 | | - - Moved from `frequenz.channels.util` to `frequenz.channels.event`. |
72 | | - |
73 | | - - `__init__`: The `name` argument was made keyword-only. The default was changed to a more readable version of `id(self)`. |
74 | | - |
75 | | - You should instantiate using `Event(name=...)` instead of `Event(...)`. |
76 | | - |
77 | | -* `FileWatcher` |
78 | | - |
79 | | - - Moved from `frequenz.channels.util` to `frequenz.channels.file_watcher`. |
80 | | - |
81 | | - - 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`). |
82 | | - |
83 | | -* `Receiver` |
84 | | - |
85 | | - - The `map()` function now takes a positional-only argument, if you were using `receiver.map(call=fun)` you should replace it with `receiver.map(func)`. |
86 | | - |
87 | | -* `SelectError` now inherits from `channels.Error` instead of `BaseException`, so you should be able to catch it with `except Exception:` or `except channels.Error:`. |
88 | | - |
89 | | -* `Selected` |
90 | | - |
91 | | - - The `value` property was renamed to `message`. |
92 | | - - `was_stopped` is now a property, you need to replace `selected.was_stopped()` with `selected.was_stopped`. |
93 | | - |
94 | | -* `Sender` |
95 | | - |
96 | | - - The `send` method now takes a positional-only argument, if you were using `sender.send(msg=message)` you should replace it with `sender.send(message)`. |
97 | | - |
98 | | -* `Timer` and support classes |
99 | | - |
100 | | - - Moved from `frequenz.channels.util` to `frequenz.channels.timer`. |
101 | | - |
102 | | -### Removals |
103 | | - |
104 | | -* `Anycast` |
105 | | - |
106 | | - - The following public properties were removed (made private): `deque`, `send_cv`, `recv_cv`. |
107 | | - |
108 | | -* `Bidirectional` |
109 | | - |
110 | | - 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. |
111 | | - |
112 | | -* `Broadcast` |
113 | | - |
114 | | - - The following public properties were removed (made private): `recv_cv`, `receivers`. |
115 | | - - `new_peekable()` was removed because `Peekable` was removed. |
116 | | - |
117 | | -* `Merge` |
118 | | - |
119 | | - Replaced by the new `merge()` function. When replacing `Merge` with `merge()` please keep in mind that this new function will raise a `ValueError` if no receivers are passed to it. |
120 | | - |
121 | | - Please note that the old `Merge` class is still also available but it was renamed to `Merger` to avoid confusion with the new `merge()` function, but it is only present for typing reasons and should not be used directly. |
122 | | - |
123 | | -* `MergeNamed` |
124 | | - |
125 | | - This class was redundant, use either the new `merge()` function or `select()` instead. |
126 | | - |
127 | | -* `Peekable` |
128 | | - |
129 | | - This class was removed because it was merely a shortcut to a receiver that caches the last message received. It did not fit the channel abstraction well and was infrequently used. |
130 | | - |
131 | | - You can replace it with a task that receives and retains the last message. |
132 | | - |
133 | | -* `Receiver.into_peekable()` was removed because `Peekable` was removed. |
134 | | - |
135 | | -* `ReceiverInvalidatedError` was removed because it was only used when converting to a `Peekable` and `Peekable` was removed. |
136 | | - |
137 | | -* `SelectErrorGroup` was removed, a Python built-in `BaseExceptionGroup` is raised instead in case of unexpected errors while finalizing a `select()` loop, which will be automatically converted to a simple `ExceptionGroup` when no exception in the groups is a `BaseException`. |
138 | | - |
139 | | -- `Timer`: |
140 | | - |
141 | | - - `periodic()` and `timeout()`: The names proved to be too confusing, please use `Timer()` and pass a missing ticks policy explicitly instead. In general you can update your code by doing: |
142 | | - |
143 | | - * `Timer.periodic(interval)` / `Timer.periodic(interval, skip_missed_ticks=True)` -> `Timer(interval, TriggerAllMissed())` |
144 | | - * `Timer.periodic(interval, skip_missed_ticks=False)` -> `Timer(interval, SkipMissedAndResync())` |
145 | | - * `Timer.timeout(interval)` -> `Timer(interval, SkipMissedAndDrift())` |
| 9 | +<!-- Here goes notes on how to upgrade from previous versions, including deprecations and what they should be replaced with --> |
146 | 10 |
|
147 | 11 | ## New Features |
148 | 12 |
|
149 | | -* A new `Broadcast.resend_latest` read-write property was added to get/set whether the latest message should be resent to new receivers. |
150 | | - |
151 | | -* `Timer()` and `Timer.reset()` now take an optional `start_delay` option to make the timer start after some delay. |
152 | | - |
153 | | - This can be useful, for example, if the timer needs to be *aligned* to a particular time. The alternative to this would be to `sleep()` for the time needed to align the timer, but if the `sleep()` call gets delayed because the event loop is busy, then a re-alignment is needed and this could go on for a while. The only way to guarantee a certain alignment (with a reasonable precision) is to delay the timer start. |
154 | | - |
155 | | -## Improvements |
156 | | - |
157 | | -* The arm64 architecture is now officially supported. |
158 | | - |
159 | | -* A new User's Guide was added to the documentation and the documentation was greately improved in general. |
160 | | - |
161 | | -* A new `merge()` function was added to replace `Merge`. |
162 | | - |
163 | | -* A warning will be logged by `Anycast` channels if senders are blocked because the channel buffer is full. |
164 | | - |
165 | | -* `Receiver`, `merge`/`Merger`, `Error` and its derived classes now use a covariant generic type, which allows the generic type to be broader than the actual type. |
166 | | - |
167 | | -* `Sender` now uses a contravariant generic type, which allows the generic type to be narrower than the required type. |
168 | | - |
169 | | -* `ChannelError` is now generic, so when accessing the `channel` attribute, the type of the channel is preserved. |
170 | | - |
171 | | -* Most classes have now a better implementation of `__str__` and `__repr__`. |
| 13 | +<!-- Here goes the main new features and examples or instructions on how to use them --> |
172 | 14 |
|
173 | 15 | ## Bug Fixes |
174 | 16 |
|
175 | | -* `Timer`: Fix bug that was causing calls to `reset()` to not reset the timer, if the timer was already being awaited. |
| 17 | +<!-- Here goes notable bug fixes that are worth a special mention or explanation --> |
0 commit comments