flowevent 1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flowevent-1.2/CHANGELOG.md +234 -0
- flowevent-1.2/LICENSE +21 -0
- flowevent-1.2/MANIFEST.in +5 -0
- flowevent-1.2/PKG-INFO +1171 -0
- flowevent-1.2/README-TR.md +1165 -0
- flowevent-1.2/README.md +1139 -0
- flowevent-1.2/benchmarks/__init__.py +1 -0
- flowevent-1.2/benchmarks/_measure.py +79 -0
- flowevent-1.2/benchmarks/benchmark_compare.py +149 -0
- flowevent-1.2/benchmarks/benchmark_pipeline.py +103 -0
- flowevent-1.2/benchmarks/benchmark_publish.py +102 -0
- flowevent-1.2/benchmarks/benchmark_replay.py +188 -0
- flowevent-1.2/benchmarks/benchmark_runtime.py +338 -0
- flowevent-1.2/benchmarks/benchmark_stream.py +67 -0
- flowevent-1.2/benchmarks/results/README.md +154 -0
- flowevent-1.2/benchmarks/results/callback_errors.json +213 -0
- flowevent-1.2/benchmarks/results/extended_publish.json +132 -0
- flowevent-1.2/benchmarks/results/interleaved_publish.json +428 -0
- flowevent-1.2/benchmarks/results/paired_baseline.json +132 -0
- flowevent-1.2/benchmarks/results/paired_extended.json +132 -0
- flowevent-1.2/benchmarks/results/pipeline.json +141 -0
- flowevent-1.2/benchmarks/results/pipeline_diagnostics.json +195 -0
- flowevent-1.2/benchmarks/results/process_peak_rss.json +52 -0
- flowevent-1.2/benchmarks/results/replay_after.txt +10 -0
- flowevent-1.2/benchmarks/results/replay_before.txt +11 -0
- flowevent-1.2/benchmarks/results/runtime_load.json +367 -0
- flowevent-1.2/benchmarks/results/stream.json +50 -0
- flowevent-1.2/benchmarks/results/v1_1_publish.json +132 -0
- flowevent-1.2/eventflow/__init__.py +123 -0
- flowevent-1.2/eventflow/_callbacks.py +22 -0
- flowevent-1.2/eventflow/_lifecycle.py +31 -0
- flowevent-1.2/eventflow/actions.py +53 -0
- flowevent-1.2/eventflow/async_event_bus.py +640 -0
- flowevent-1.2/eventflow/base.py +180 -0
- flowevent-1.2/eventflow/callback.py +318 -0
- flowevent-1.2/eventflow/compatibility.py +14 -0
- flowevent-1.2/eventflow/context.py +103 -0
- flowevent-1.2/eventflow/contracts.py +40 -0
- flowevent-1.2/eventflow/engine.py +466 -0
- flowevent-1.2/eventflow/errors.py +21 -0
- flowevent-1.2/eventflow/event_bus.py +594 -0
- flowevent-1.2/eventflow/filtering.py +57 -0
- flowevent-1.2/eventflow/history.py +111 -0
- flowevent-1.2/eventflow/observability.py +133 -0
- flowevent-1.2/eventflow/pipeline/__init__.py +7 -0
- flowevent-1.2/eventflow/pipeline/async_.py +129 -0
- flowevent-1.2/eventflow/pipeline/base.py +203 -0
- flowevent-1.2/eventflow/pipeline/contracts.py +24 -0
- flowevent-1.2/eventflow/pipeline/registry.py +95 -0
- flowevent-1.2/eventflow/pipeline/sync.py +92 -0
- flowevent-1.2/eventflow/py.typed +0 -0
- flowevent-1.2/eventflow/scopes.py +185 -0
- flowevent-1.2/eventflow/stream.py +241 -0
- flowevent-1.2/eventflow/subscription.py +116 -0
- flowevent-1.2/examples/__init__.py +1 -0
- flowevent-1.2/examples/bus_stream.py +46 -0
- flowevent-1.2/examples/integrated.py +88 -0
- flowevent-1.2/flowevent.egg-info/PKG-INFO +1171 -0
- flowevent-1.2/flowevent.egg-info/SOURCES.txt +80 -0
- flowevent-1.2/flowevent.egg-info/dependency_links.txt +1 -0
- flowevent-1.2/flowevent.egg-info/requires.txt +8 -0
- flowevent-1.2/flowevent.egg-info/top_level.txt +1 -0
- flowevent-1.2/pyproject.toml +70 -0
- flowevent-1.2/setup.cfg +4 -0
- flowevent-1.2/tests/api_v1_1.json +142 -0
- flowevent-1.2/tests/api_v1_2.json +142 -0
- flowevent-1.2/tests/test_benchmarks.py +154 -0
- flowevent-1.2/tests/test_bus.py +1567 -0
- flowevent-1.2/tests/test_callback.py +271 -0
- flowevent-1.2/tests/test_context.py +110 -0
- flowevent-1.2/tests/test_delivery_limits.py +322 -0
- flowevent-1.2/tests/test_engine.py +402 -0
- flowevent-1.2/tests/test_filtering.py +35 -0
- flowevent-1.2/tests/test_integration.py +125 -0
- flowevent-1.2/tests/test_lifecycle.py +50 -0
- flowevent-1.2/tests/test_middleware_limits.py +42 -0
- flowevent-1.2/tests/test_observability.py +164 -0
- flowevent-1.2/tests/test_pipeline.py +332 -0
- flowevent-1.2/tests/test_public_contracts.py +134 -0
- flowevent-1.2/tests/test_scopes.py +250 -0
- flowevent-1.2/tests/test_stream.py +373 -0
- flowevent-1.2/tests/test_subscription.py +116 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
## [v1.2] - 2026-11-02
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Add independent `Pipeline[T]` and `AsyncPipeline[T]` execution with named
|
|
12
|
+
stages, identity-preserving decorators, stable before/after ordering,
|
|
13
|
+
replacement, enable/disable controls, and immutable execution snapshots.
|
|
14
|
+
- Add ordered pipeline middleware with around execution, explicit
|
|
15
|
+
short-circuit/recovery, and single-use, caller-owned continuations.
|
|
16
|
+
- Add `PipelineExecutionError` with the failing component, input context,
|
|
17
|
+
original cause, and separately retained observer failures.
|
|
18
|
+
- Add single-consumer `AsyncStream` with lazy sync/async map and filter,
|
|
19
|
+
tuple batching, bounded prefetch, backpressure, and cancellation-safe closure.
|
|
20
|
+
- Add `SubscriptionScope` and `AsyncSubscriptionScope` for existing cancellation
|
|
21
|
+
handles, reverse-order cleanup, grouped failures, and retryable shutdown.
|
|
22
|
+
- Add optional immutable `EventEnvelope`, scoped correlation identifiers,
|
|
23
|
+
`PipelineObservation`, and thread-safe aggregate `PipelineStats`.
|
|
24
|
+
- Add v1.1 public signature/decorator regression contracts, executable README
|
|
25
|
+
checks, composed bus/pipeline/stream examples, and latency/allocation benchmarks.
|
|
26
|
+
- Report branch coverage alongside line coverage in the CI test matrix.
|
|
27
|
+
- Add an equivalent native async map/filter case to the stream benchmark so its
|
|
28
|
+
API overhead can be compared separately from raw source iteration.
|
|
29
|
+
- Add repeatable publisher-contention, `max_concurrency`, callback-error,
|
|
30
|
+
middleware, periodic-schedule resource, and 100,000-event memory-soak benchmarks.
|
|
31
|
+
- Add an opt-in per-publish async callback concurrency limit and expose it
|
|
32
|
+
through async engine-created channels.
|
|
33
|
+
- Add sparse filtered-history measurements to the replay benchmark and a
|
|
34
|
+
CodeQL security-analysis workflow with weekly dependency update checks.
|
|
35
|
+
- Document shared contracts, snapshot ownership, middleware ordering, stream
|
|
36
|
+
backpressure, context propagation, and intentional architectural limits.
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- Refill bounded async delivery slots as callbacks finish instead of waiting
|
|
41
|
+
for every callback in a fixed batch.
|
|
42
|
+
- Avoid an extra full result-list copy when bounded async delivery completes.
|
|
43
|
+
- Clarify that another distribution installing the shared `eventflow` import
|
|
44
|
+
package in the same environment can overwrite or conflict with package files.
|
|
45
|
+
- Document that sparse filtered replay scans history synchronously on the async
|
|
46
|
+
event loop and may delay unrelated tasks.
|
|
47
|
+
- Use `flowevent` as the PyPI distribution name while keeping EventFlow as the
|
|
48
|
+
library name and `eventflow` as the Python import package.
|
|
49
|
+
- Bound pipeline middleware registrations at 64 to fail before exhausting the
|
|
50
|
+
Python call stack, and update `PipelineStats` in place rather than allocating
|
|
51
|
+
a new metrics snapshot for every observation.
|
|
52
|
+
- Load new execution components lazily through the package exports so ordinary
|
|
53
|
+
bus imports and publication do not initialize optional execution machinery.
|
|
54
|
+
- Keep the PEP 561 marker in built distributions and verify it in installed-
|
|
55
|
+
artifact CI.
|
|
56
|
+
- Extend CI typing to the runnable examples and benchmarks, require at least
|
|
57
|
+
90% pipeline line coverage, and smoke-test new APIs from installed artifacts.
|
|
58
|
+
The existing 88% package coverage floor and Python/platform matrix remain.
|
|
59
|
+
- Set separate branch-coverage floors for callback, callback helpers, base bus,
|
|
60
|
+
and async bus modules so package-wide coverage cannot hide core regressions.
|
|
61
|
+
- Refresh the recorded stream benchmark with equivalent native and EventFlow
|
|
62
|
+
map/filter work.
|
|
63
|
+
- Document that custom `EventHistory` implementations must synchronize all
|
|
64
|
+
operations and produce query results from consistent snapshots.
|
|
65
|
+
- Limit the sync bus executor option to `ThreadPoolExecutor` and document the
|
|
66
|
+
cross-bus reentrant delivery behavior for shared pools.
|
|
67
|
+
- Clarify that `clear()` leaves history and periodic schedules running, while
|
|
68
|
+
`close()` stops schedules.
|
|
69
|
+
- Normalize timezone-aware `EventEnvelope` timestamps to UTC and warn against
|
|
70
|
+
unpickling data from untrusted sources.
|
|
71
|
+
|
|
72
|
+
### Fixed
|
|
73
|
+
|
|
74
|
+
- Cancel and finish timed callback tasks when their invoking task is cancelled,
|
|
75
|
+
including when cancellation is repeated during callback cleanup.
|
|
76
|
+
- Reject closing an `AsyncStream` from its active reader task with `RuntimeError`
|
|
77
|
+
instead of allowing a self-wait deadlock; the read error path still closes
|
|
78
|
+
the stream and its upstream sources.
|
|
79
|
+
- Reject awaitable results from synchronous callback hooks and event-bus
|
|
80
|
+
actions, closing coroutine results before reporting the error.
|
|
81
|
+
- Report a clear cleanup error when an async cancellation handle's `cancel()`
|
|
82
|
+
returns a non-awaitable; document that the scope validates this at close
|
|
83
|
+
because checking during `add()` would invoke cancellation.
|
|
84
|
+
- Recheck bus state when registering a periodic publisher so a concurrent close
|
|
85
|
+
cannot be followed by a newly started worker thread.
|
|
86
|
+
- Preserve `EventEnvelope` metadata immutability while supporting
|
|
87
|
+
`dataclasses.asdict()` and pickle for serializable payloads.
|
|
88
|
+
- Restore subscription activity when sync or async removal fails so cancellation
|
|
89
|
+
scopes and callers can retry cleanup.
|
|
90
|
+
- Reject non-boolean results from event and stream filter predicates instead of
|
|
91
|
+
treating truthy or falsey values as matches.
|
|
92
|
+
- Preserve a stream source failure when closing also fails, retain both errors
|
|
93
|
+
through exception chaining, and still attempt upstream cleanup.
|
|
94
|
+
- Enforce single-task stream ownership between reads so concurrent transformed
|
|
95
|
+
consumption cannot steal items from the source.
|
|
96
|
+
- Continue scope cleanup after handle-owned cancellation or other BaseException
|
|
97
|
+
interrupts, retaining failed handles and preserving additional cleanup errors.
|
|
98
|
+
- Keep synchronous `wait_for()` waiting for its claimed one-shot callback when
|
|
99
|
+
an unrelated condition notification arrives before the value is captured.
|
|
100
|
+
- Prevent deadlock when callbacks publish through different buses sharing one
|
|
101
|
+
saturated thread pool.
|
|
102
|
+
- Make concurrent async subscription cancellation wait for the in-flight
|
|
103
|
+
removal result so scopes retain handles after a failed removal.
|
|
104
|
+
- Cancel and drain a `Task` or `Future` returned by an async callback when its
|
|
105
|
+
timeout budget expires before callback delivery begins.
|
|
106
|
+
- Preserve read-only `EventEnvelope.metadata` after `copy.deepcopy()` and close
|
|
107
|
+
async middleware continuations that are created but never awaited.
|
|
108
|
+
- Reject unsupported history values, non-thread executors, closed engine buses,
|
|
109
|
+
boolean schedule intervals, and non-boolean callback predicate results at
|
|
110
|
+
the relevant API boundary.
|
|
111
|
+
- Prevent multiple engine instances from claiming one sync or async bus, including
|
|
112
|
+
concurrent registration races, without retaining the owner after its lifetime.
|
|
113
|
+
|
|
114
|
+
## [v1.1] - 2026-10-25
|
|
115
|
+
|
|
116
|
+
### Added
|
|
117
|
+
|
|
118
|
+
- Ship the PEP 561 `py.typed` marker and run tests, Ruff, and Pyright across
|
|
119
|
+
supported Python versions and Linux, Windows, and macOS in GitHub Actions.
|
|
120
|
+
- Expose typed filter and replay options on the engine subscription methods.
|
|
121
|
+
- Check package line coverage and build, inspect, rebuild, and install wheel and
|
|
122
|
+
source distributions in CI.
|
|
123
|
+
- Audit declared runtime dependencies for known vulnerabilities in CI.
|
|
124
|
+
- Add a standalone benchmark for history latest/query and sync/async replay
|
|
125
|
+
paths.
|
|
126
|
+
|
|
127
|
+
### Changed
|
|
128
|
+
|
|
129
|
+
- Clarify that bus shutdown does not wait for callbacks already running in
|
|
130
|
+
active publish calls.
|
|
131
|
+
- Document sequential and concurrent callback cancellation semantics, that
|
|
132
|
+
cancellation cannot undo callback side effects, and the cooperative limits
|
|
133
|
+
of async callback timeouts.
|
|
134
|
+
- Request only the requested replay window from history for unfiltered
|
|
135
|
+
subscriptions, avoiding full-history copies with the built-in memory history.
|
|
136
|
+
- Document that custom history `append()` implementations run under the
|
|
137
|
+
publication lock and must remain fast and non-reentrant.
|
|
138
|
+
- Document periodic error reporting, exclusive engine ownership, and async
|
|
139
|
+
publication/statistics ordering semantics.
|
|
140
|
+
- Define `PublishResult.matched` as subscriptions selected for immediate
|
|
141
|
+
delivery, excluding events buffered during replay setup.
|
|
142
|
+
- Pin GitHub Actions to the full commit SHAs used by the verified workflow run.
|
|
143
|
+
|
|
144
|
+
### Fixed
|
|
145
|
+
|
|
146
|
+
- Reject asynchronous event filter predicates instead of treating their
|
|
147
|
+
coroutine objects as truthy matches.
|
|
148
|
+
- Remove cancellation-sensitive awaits from periodic task cleanup so a
|
|
149
|
+
repeated cancellation cannot leave a finished schedule registered.
|
|
150
|
+
- Keep async periodic schedules registered until task cancellation completes,
|
|
151
|
+
including when cancellation arrives before the coroutine starts.
|
|
152
|
+
- Let repeated async subscription cancellation retry removal after a lock-wait
|
|
153
|
+
cancellation, and preserve `wait_for()` cleanup during repeated cancellation.
|
|
154
|
+
- Preserve unfiltered history fast paths through bus queries and validate
|
|
155
|
+
filter conflicts even when history is disabled.
|
|
156
|
+
- Reject awaitable results from synchronous callbacks during direct, executor,
|
|
157
|
+
and replay delivery, closing coroutine objects before reporting the error.
|
|
158
|
+
- Prevent registering one bus instance under multiple engine channel names,
|
|
159
|
+
including while a removed channel is still closing.
|
|
160
|
+
- Release synchronous periodic schedule capacity when its worker thread cannot
|
|
161
|
+
start.
|
|
162
|
+
- Wake synchronous `wait_for()` calls when `clear()` removes their subscriptions.
|
|
163
|
+
- Run Pyright against the Python version selected by each CI matrix job.
|
|
164
|
+
- Keep cancelled periodic publishers under bus ownership until their threads
|
|
165
|
+
or tasks have actually finished.
|
|
166
|
+
- Make the replay benchmark use the checkout under test when run as a script.
|
|
167
|
+
- Clean up replay subscriptions when replay filtering or setup raises, and make
|
|
168
|
+
asynchronous bus shutdown safe to retry after caller cancellation.
|
|
169
|
+
- Attempt to close every engine channel, retain channels whose shutdown failed,
|
|
170
|
+
and report collected failures together.
|
|
171
|
+
- Report a cancelled callback as a delivery failure in concurrent async mode
|
|
172
|
+
while preserving cancellation of the publishing task.
|
|
173
|
+
- Validate replay counts, history query limits, and wait timeouts consistently,
|
|
174
|
+
including boolean, fractional, negative, and non-finite values.
|
|
175
|
+
|
|
176
|
+
## [v1.0] - 2026-10-24
|
|
177
|
+
|
|
178
|
+
### Added
|
|
179
|
+
|
|
180
|
+
- Expose the package version as `eventflow.__version__`.
|
|
181
|
+
- Extracted the event subsystem from [Vehicle Autonomy Core](https://github.com/TahsinCr/vehicle-autonomy-core)
|
|
182
|
+
into the standalone EventFlow package. It provides thread-safe EventBus
|
|
183
|
+
and asyncio-native AsyncEventBus implementations with immutable generic
|
|
184
|
+
EventFilter values, type and predicate matching, one-time and limited
|
|
185
|
+
subscriptions, replay, blocking or asynchronous waits, and cancellable
|
|
186
|
+
periodic publishing.
|
|
187
|
+
- Added optional bounded EventHistory and MemoryEventHistory storage, latest
|
|
188
|
+
and query helpers, PublishResult and EventBusStats, configurable ErrorPolicy,
|
|
189
|
+
and sequential or concurrent asynchronous delivery.
|
|
190
|
+
- Added reusable synchronous and asynchronous bus actions for before, after,
|
|
191
|
+
subscriber-error, and wait-timeout handling, with typed error and timeout
|
|
192
|
+
contexts.
|
|
193
|
+
- Added EventEngine and AsyncEventEngine for lazy named channels, shared
|
|
194
|
+
defaults, and aggregate lifecycle management.
|
|
195
|
+
- Added callable CallbackSubscription policies for frequency limits, maximum
|
|
196
|
+
calls, one-time delivery, timeouts, predicates, enable/disable controls, and
|
|
197
|
+
before/success/error/timeout/after hooks. Framework callback timeouts raise
|
|
198
|
+
CallbackTimeoutError.
|
|
199
|
+
- Added bounded replay buffers and periodic schedule capacity, a bounded
|
|
200
|
+
synchronous shutdown timeout with EventShutdownTimeoutError, and English and
|
|
201
|
+
Turkish event guides.
|
|
202
|
+
|
|
203
|
+
### Changed
|
|
204
|
+
|
|
205
|
+
- Changed the project license from GPL-3.0-only to MIT.
|
|
206
|
+
- Renamed the distribution and public import package to EventFlow (`eventflow`).
|
|
207
|
+
- Preserved Python 3.10 support through one compatibility module. Python 3.10 uses conditional
|
|
208
|
+
backports for StrEnum and ExceptionGroup; Python 3.11 and newer use the
|
|
209
|
+
standard-library implementations.
|
|
210
|
+
- Shared capacity and timeout validation between both buses. Unfiltered latest
|
|
211
|
+
reads are constant time; bounded queries stop after collecting the requested
|
|
212
|
+
newest matches, while filtered history predicates run against a stable
|
|
213
|
+
snapshot.
|
|
214
|
+
- Deliver replayed events before live events buffered during subscription
|
|
215
|
+
setup.
|
|
216
|
+
- Reorganized the English and Turkish READMEs into a progressive usage guide
|
|
217
|
+
with practical examples, behavioral explanations, and a public API reference.
|
|
218
|
+
|
|
219
|
+
### Fixed
|
|
220
|
+
|
|
221
|
+
- Preserve narrowed history filters during subscription setup. Evaluate replay
|
|
222
|
+
and history predicates outside internal locks against stable snapshots.
|
|
223
|
+
- Make replay-buffer overflow visible and isolate it to the affected
|
|
224
|
+
subscription. A full replay buffer does not silently discard live events or
|
|
225
|
+
interrupt other subscribers.
|
|
226
|
+
- Close the AsyncEventBus.wait_for() registration race, clean up subscriptions
|
|
227
|
+
when asynchronous replay is cancelled, and prevent reentrant publishing from
|
|
228
|
+
deadlocking a single-worker executor.
|
|
229
|
+
- Apply the same admission-to-callback timeout budget to synchronous and
|
|
230
|
+
asynchronous callback policies, and keep a user-raised TimeoutError distinct
|
|
231
|
+
from a framework timeout.
|
|
232
|
+
- Retain ownership of timed-out synchronous publisher threads so a later
|
|
233
|
+
close() can finish joining them, and join synchronous periodic publisher
|
|
234
|
+
threads during shutdown.
|
flowevent-1.2/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 TahsinCr
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|