Skip to content

Tags: TotalWineLabs/kaspr

Tags

v0.11.20

Toggle v0.11.20's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Release v0.11.20 (#69) (#70)

* Update requirements.txt

* Bump version to 0.11.20

v0.11.19

Toggle v0.11.19's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Release v0.11.19 (#68) (#69)

* Add lazy topic declaration for TopicOutSpec

TopicOutSpec now supports a `declare` flag and producer topic options (`partitions`, `retention`, `compacting`, `deleting`, `replicas`, `config`) via schema/model fields. Sending now resolves and caches the topic once, optionally calls `maybe_declare()` only once per topic name using an async lock, then sends as before. Tests were expanded to verify single lazy declaration behavior and that topic creation receives the spec-level options.

* Bump version to 0.11.19

v0.11.18

Toggle v0.11.18's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Release v0.11.18 (#67) (#68)

* Bump twm-faust and clarify first-op behavior

Update `twm-faust` minimum version from `1.17.18` to `1.17.19` while keeping the same upper bound. Also add a clarifying comment in `TaskProcessorTopicSendOperator.process` to explain that the first task pipeline operation is invoked without an input value, documenting why `should_skip` is called differently for `first_op`.

* Bump version to 0.11.18

v0.11.17

Toggle v0.11.17's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Release v0.11.17 (#66) (#67)

* Fix topic-send pass-through semantics

Update agent, task, and webview topic-send operators to honor `pass_through` consistently: skipped records now return the original value when pass-through is enabled, and post-send fallback to `skip_value` only occurs when both `pass_through` and `ack` are disabled. Expanded tests cover `None` payload pass-through, predicate-skip downstream continuation for agent pipelines, and task pipeline preservation of `None` in first-op topic sends.

* Bump version to 0.11.17

v0.11.16

Toggle v0.11.16's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Release v0.11.16 (#65) (#66)

* Add agent topic_send operator support

Introduces `AgentProcessorTopicSendOperator` and wires it into agent operation selection, model exports, and marshmallow schemas so agent pipelines can declare `topic_send` steps. Topic-send processing now treats `None` send results as `skip_value` (matching pass-through semantics) across agent, task, and webview operators. Expanded tests cover schema loading, pass-through vs non-pass-through pipeline behavior, predicate skips, and error propagation for agent topic sends.

* Bump version to 0.11.16

v0.11.15

Toggle v0.11.15's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Release v0.11.15 (#64) (#65)

* Update prometheus_monitor.py

* Handle missing lag in Prometheus monitor

Guard janitor location lag updates when the lag value is absent, and only mark the app as recovering on rebalance return when table recovery is actually in progress. This avoids emitting invalid metric values and makes the health metric reflect the real recovery state.

* Bump version to 0.11.15

v0.11.14

Toggle v0.11.14's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Release v0.11.14 (#63) (#64)

* Update requirements.txt

* Bump version to 0.11.14

v0.11.13

Toggle v0.11.13's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Release v0.11.13 (#62) (#63)

* Update prometheus_monitor.py

* Bump version to 0.11.13

v0.11.12

Toggle v0.11.12's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Release v0.11.12 (#62)

* Release v0.11.11 (#60)

* Release v0.11.10 (#58)

* Release v0.11.8 (#56)

* Release v0.11.7 (#55)

* Release v0.10.6 (#46)

* Pause checkpoints until in-flight ops finish

Prevent checkpoints from advancing while deliveries/removals are still in-flight. Add _pending_delivery_count and _pending_removal_count to Dispatcher/Janitor, incrementing when items are queued and decrementing on ack, and require these counters (and _unacked_deliveries being empty) before updating periodic checkpoints to avoid losing or duplicating work during rebalances. Also wait for dispatchers/janitors to drain in MessageScheduler.on_partitions_revoked before flushing checkpoints. Bump package version to 0.10.6dev.

* Bump version and clear partition metrics on revoke

Bump package version to 0.10.6dev2.

In the Prometheus monitor, clear partition-level gauge metrics when a dispatcher or janitor is revoked (remove last_location_time, last_location_seq, location_lag, and active_deliveries/active_removals) so stale values are no longer reported. Also fix janitor revoke to use janitor_info labels instead of dispatcher_info.

* Add can_distribute event and rebalance timeout

* Bump to 0.10.6dev4; drop revocation wait

* Wait for in-flight work on partition revocation

Bump package version to 0.10.6dev5 and enhance MessageScheduler.on_partitions_revoked to wait for any in-flight deliveries/removals by awaiting wait_empty_dispatchers_and_janitors() with a 10s timeout. Logs a warning on timeout, then proceeds to flush checkpoints and stop/revoke dispatchers and janitors.

* Bump version to 0.10.6

* Add cron ticker and cron registry support

Introduce cron-based scheduling support: add a CronTicker service, cron registry table and related types, settings, and utils. New kaspr/scheduler/ticker.py implements a per-partition CronTicker that pre-materializes upcoming cron fires into the timetable; manager integration creates/assigns/revokes tickers and exposes pause/resume behavior. MessageScheduler now handles CRON_ADD/CRON_CANCEL/CRON_PAUSE/CRON_RESUME actions (and routes cron requests to the actions topic), stores cron definitions in a cron-registry table, and cancels or materializes fired entries as needed. Utilities added in scheduler/utils.py: validate_cron_expr, compute_next_fire, compute_fires_in_window, cron_min_interval (uses croniter). New type kaspr/types/ticker.py and settings entries to control enabling, tick interval, buffer and minimum interval. Safety checks include cron expression validation and enforcement of a minimum allowed interval before registering a cron.

* Add cron due-index and ticker recovery

Introduce a time-bucketed cron due-index to avoid scanning the entire cron registry on each tick and add recovery/catch-up logic for missed cron fires. Key changes:

- Scheduler manager: add prepare_cron_due_index, expose cron_due_index, gate cron-related wiring/actions on scheduler_cron_enabled, and update the due-index on cron add/pause/resume/cancel.
- CronTicker: switch materialization to scan the due-index by minute-bucket (prefix_scan), add catch-up for missed fires on activation, and re-index crons to their next fire. New helpers collect and process due entries and materialize fires efficiently.
- Utils/types: add due_index_key and due_index_prefix helpers; extend KasprTableT with prefix_scan and items_for_partition and implement KasprTable.items_for_partition.
- Settings: add SCHEDULER_CRON_RECOVERY_LOOKBACK_SECONDS, increase default tick buffer, and add validation ensuring buffer/tick/min-interval invariants.
- Bump twm-faust requirement patch version.

These changes make cron tick cost proportional to due crons, improve resilience on restarts, and add configuration validation to prevent misconfiguration that could miss cron fires.

* Add missed_fire_policy for cron recovery

Introduce a missed_fire_policy to control how missed cron fires are handled on recovery. The scheduler now reads an "x-scheduler-cron-missed-fire-policy" header (default "replay") and stores missed_fire_policy on cron registry entries. On resume, manager respects the policy: "replay" preserves last_fire so missed triggers are materialized, while "skip" advances last_fire to now. CronTicker._catchup_missed_fires was rewritten to scan stale due-index buckets, separate entries by policy, replay missed fires or advance skip-entries to now (via _advance_stale_entries_to_now), and then materialize the current window. Removed the SCHEDULER_CRON_RECOVERY_LOOKBACK setting and its usage; recovery now operates by scanning the due-index instead of a bounded lookback window. Added logging to indicate recovery actions and policy decisions.

* Fix cron pause/resume and materialize past fires

Clean up duplicate header constant and adjust cron scheduling behavior around creation, pause/resume, and past fires. Use entry.created_at (not last_fire) when materializing from creation, record paused_at on pause, and on resume set last_fire to the pause time for "replay" so only the paused gap is backfilled. Ensure the due-index is written from the resume time. In the ticker, materialize past fire events into the current time slot (preserving the original fire timestamp in a header) so the Dispatcher—which only scans forward—will pick them up, update timetable locations accordingly, and set last_fire when updating the registry.

* Update __init__.py

* Release v0.11.0 (#47)

* Add cron ticker and cron registry support

Introduce cron-based scheduling support: add a CronTicker service, cron registry table and related types, settings, and utils. New kaspr/scheduler/ticker.py implements a per-partition CronTicker that pre-materializes upcoming cron fires into the timetable; manager integration creates/assigns/revokes tickers and exposes pause/resume behavior. MessageScheduler now handles CRON_ADD/CRON_CANCEL/CRON_PAUSE/CRON_RESUME actions (and routes cron requests to the actions topic), stores cron definitions in a cron-registry table, and cancels or materializes fired entries as needed. Utilities added in scheduler/utils.py: validate_cron_expr, compute_next_fire, compute_fires_in_window, cron_min_interval (uses croniter). New type kaspr/types/ticker.py and settings entries to control enabling, tick interval, buffer and minimum interval. Safety checks include cron expression validation and enforcement of a minimum allowed interval before registering a cron.

* Add cron due-index and ticker recovery

Introduce a time-bucketed cron due-index to avoid scanning the entire cron registry on each tick and add recovery/catch-up logic for missed cron fires. Key changes:

- Scheduler manager: add prepare_cron_due_index, expose cron_due_index, gate cron-related wiring/actions on scheduler_cron_enabled, and update the due-index on cron add/pause/resume/cancel.
- CronTicker: switch materialization to scan the due-index by minute-bucket (prefix_scan), add catch-up for missed fires on activation, and re-index crons to their next fire. New helpers collect and process due entries and materialize fires efficiently.
- Utils/types: add due_index_key and due_index_prefix helpers; extend KasprTableT with prefix_scan and items_for_partition and implement KasprTable.items_for_partition.
- Settings: add SCHEDULER_CRON_RECOVERY_LOOKBACK_SECONDS, increase default tick buffer, and add validation ensuring buffer/tick/min-interval invariants.
- Bump twm-faust requirement patch version.

These changes make cron tick cost proportional to due crons, improve resilience on restarts, and add configuration validation to prevent misconfiguration that could miss cron fires.

* Add missed_fire_policy for cron recovery

Introduce a missed_fire_policy to control how missed cron fires are handled on recovery. The scheduler now reads an "x-scheduler-cron-missed-fire-policy" header (default "replay") and stores missed_fire_policy on cron registry entries. On resume, manager respects the policy: "replay" preserves last_fire so missed triggers are materialized, while "skip" advances last_fire to now. CronTicker._catchup_missed_fires was rewritten to scan stale due-index buckets, separate entries by policy, replay missed fires or advance skip-entries to now (via _advance_stale_entries_to_now), and then materialize the current window. Removed the SCHEDULER_CRON_RECOVERY_LOOKBACK setting and its usage; recovery now operates by scanning the due-index instead of a bounded lookback window. Added logging to indicate recovery actions and policy decisions.

* Fix cron pause/resume and materialize past fires

Clean up duplicate header constant and adjust cron scheduling behavior around creation, pause/resume, and past fires. Use entry.created_at (not last_fire) when materializing from creation, record paused_at on pause, and on resume set last_fire to the pause time for "replay" so only the paused gap is backfilled. Ensure the due-index is written from the resume time. In the ticker, materialize past fire events into the current time slot (preserving the original fire timestamp in a header) so the Dispatcher—which only scans forward—will pick them up, update timetable locations accordingly, and set last_fire when updating the registry.

* Update __init__.py

* Update ticker.py

* Bump version to 0.11.1

* Bump version to 0.11.2

* Release v0.11.5 (#52)

* Release v0.10.6 (#46)

* Pause checkpoints until in-flight ops finish

Prevent checkpoints from advancing while deliveries/removals are still in-flight. Add _pending_delivery_count and _pending_removal_count to Dispatcher/Janitor, incrementing when items are queued and decrementing on ack, and require these counters (and _unacked_deliveries being empty) before updating periodic checkpoints to avoid losing or duplicating work during rebalances. Also wait for dispatchers/janitors to drain in MessageScheduler.on_partitions_revoked before flushing checkpoints. Bump package version to 0.10.6dev.

* Bump version and clear partition metrics on revoke

Bump package version to 0.10.6dev2.

In the Prometheus monitor, clear partition-level gauge metrics when a dispatcher or janitor is revoked (remove last_location_time, last_location_seq, location_lag, and active_deliveries/active_removals) so stale values are no longer reported. Also fix janitor revoke to use janitor_info labels instead of dispatcher_info.

* Add can_distribute event and rebalance timeout

* Bump to 0.10.6dev4; drop revocation wait

* Wait for in-flight work on partition revocation

Bump package version to 0.10.6dev5 and enhance MessageScheduler.on_partitions_revoked to wait for any in-flight deliveries/removals by awaiting wait_empty_dispatchers_and_janitors() with a 10s timeout. Logs a warning on timeout, then proceeds to flush checkpoints and stop/revoke dispatchers and janitors.

* Bump version to 0.10.6

* Release v0.11.0 (#47)

* Add cron ticker and cron registry support

Introduce cron-based scheduling support: add a CronTicker service, cron registry table and related types, settings, and utils. New kaspr/scheduler/ticker.py implements a per-partition CronTicker that pre-materializes upcoming cron fires into the timetable; manager integration creates/assigns/revokes tickers and exposes pause/resume behavior. MessageScheduler now handles CRON_ADD/CRON_CANCEL/CRON_PAUSE/CRON_RESUME actions (and routes cron requests to the actions topic), stores cron definitions in a cron-registry table, and cancels or materializes fired entries as needed. Utilities added in scheduler/utils.py: validate_cron_expr, compute_next_fire, compute_fires_in_window, cron_min_interval (uses croniter). New type kaspr/types/ticker.py and settings entries to control enabling, tick interval, buffer and minimum interval. Safety checks include cron expression validation and enforcement of a minimum allowed interval before registering a cron.

* Add cron due-index and ticker recovery

Introduce a time-bucketed cron due-index to avoid scanning the entire cron registry on each tick and add recovery/catch-up logic for missed cron fires. Key changes:

- Scheduler manager: add prepare_cron_due_index, expose cron_due_index, gate cron-related wiring/actions on scheduler_cron_enabled, and update the due-index on cron add/pause/resume/cancel.
- CronTicker: switch materialization to scan the due-index by minute-bucket (prefix_scan), add catch-up for missed fires on activation, and re-index crons to their next fire. New helpers collect and process due entries and materialize fires efficiently.
- Utils/types: add due_index_key and due_index_prefix helpers; extend KasprTableT with prefix_scan and items_for_partition and implement KasprTable.items_for_partition.
- Settings: add SCHEDULER_CRON_RECOVERY_LOOKBACK_SECONDS, increase default tick buffer, and add validation ensuring buffer/tick/min-interval invariants.
- Bump twm-faust requirement patch version.

These changes make cron tick cost proportional to due crons, improve resilience on restarts, and add configuration validation to prevent misconfiguration that could miss cron fires.

* Add missed_fire_policy for cron recovery

Introduce a missed_fire_policy to control how missed cron fires are handled on recovery. The scheduler now reads an "x-scheduler-cron-missed-fire-policy" header (default "replay") and stores missed_fire_policy on cron registry entries. On resume, manager respects the policy: "replay" preserves last_fire so missed triggers are materialized, while "skip" advances last_fire to now. CronTicker._catchup_missed_fires was rewritten to scan stale due-index buckets, separate entries by policy, replay missed fires or advance skip-entries to now (via _advance_stale_entries_to_now), and then materialize the current window. Removed the SCHEDULER_CRON_RECOVERY_LOOKBACK setting and its usage; recovery now operates by scanning the due-index instead of a bounded lookback window. Added logging to indicate recovery actions and policy decisions.

* Fix cron pause/resume and materialize past fires

Clean up duplicate header constant and adjust cron scheduling behavior around creation, pause/resume, and past fires. Use entry.created_at (not last_fire) when materializing from creation, record paused_at on pause, and on resume set last_fire to the pause time for "replay" so only the paused gap is backfilled. Ensure the due-index is written from the resume time. In the ticker, materialize past fire events into the current time slot (preserving the original fire timestamp in a header) so the Dispatcher—which only scans forward—will pick them up, update timetable locations accordingly, and set last_fire when updating the registry.

* Update __init__.py

* Release v0.11.2 (#49)

* Add cron ticker and cron registry support

Introduce cron-based scheduling support: add a CronTicker service, cron registry table and related types, settings, and utils. New kaspr/scheduler/ticker.py implements a per-partition CronTicker that pre-materializes upcoming cron fires into the timetable; manager integration creates/assigns/revokes tickers and exposes pause/resume behavior. MessageScheduler now handles CRON_ADD/CRON_CANCEL/CRON_PAUSE/CRON_RESUME actions (and routes cron requests to the actions topic), stores cron definitions in a cron-registry table, and cancels or materializes fired entries as needed. Utilities added in scheduler/utils.py: validate_cron_expr, compute_next_fire, compute_fires_in_window, cron_min_interval (uses croniter). New type kaspr/types/ticker.py and settings entries to control enabling, tick interval, buffer and minimum interval. Safety checks include cron expression validation and enforcement of a minimum allowed interval before registering a cron.

* Add cron due-index and ticker recovery

Introduce a time-bucketed cron due-index to avoid scanning the entire cron registry on each tick and add recovery/catch-up logic for missed cron fires. Key changes:

- Scheduler manager: add prepare_cron_due_index, expose cron_due_index, gate cron-related wiring/actions on scheduler_cron_enabled, and update the due-index on cron add/pause/resume/cancel.
- CronTicker: switch materialization to scan the due-index by minute-bucket (prefix_scan), add catch-up for missed fires on activation, and re-index crons to their next fire. New helpers collect and process due entries and materialize fires efficiently.
- Utils/types: add due_index_key and due_index_prefix helpers; extend KasprTableT with prefix_scan and items_for_partition and implement KasprTable.items_for_partition.
- Settings: add SCHEDULER_CRON_RECOVERY_LOOKBACK_SECONDS, increase default tick buffer, and add validation ensuring buffer/tick/min-interval invariants.
- Bump twm-faust requirement patch version.

These changes make cron tick cost proportional to due crons, improve resilience on restarts, and add configuration validation to prevent misconfiguration that could miss cron fires.

* Add missed_fire_policy for cron recovery

Introduce a missed_fire_policy to control how missed cron fires are handled on recovery. The scheduler now reads an "x-scheduler-cron-missed-fire-policy" header (default "replay") and stores missed_fire_policy on cron registry entries. On resume, manager respects the policy: "replay" preserves last_fire so missed triggers are materialized, while "skip" advances last_fire to now. CronTicker._catchup_missed_fires was rewritten to scan stale due-index buckets, separate entries by policy, replay missed fires or advance skip-entries to now (via _advance_stale_entries_to_now), and then materialize the current window. Removed the SCHEDULER_CRON_RECOVERY_LOOKBACK setting and its usage; recovery now operates by scanning the due-index instead of a bounded lookback window. Added logging to indicate recovery actions and policy decisions.

* Fix cron pause/resume and materialize past fires

Clean up duplicate header constant and adjust cron scheduling behavior around creation, pause/resume, and past fires. Use entry.created_at (not last_fire) when materializing from creation, record paused_at on pause, and on resume set last_fire to the pause time for "replay" so only the paused gap is backfilled. Ensure the due-index is written from the resume time. In the ticker, materialize past fire events into the current time slot (preserving the original fire timestamp in a header) so the Dispatcher—which only scans forward—will pick them up, update timetable locations accordingly, and set last_fire when updating the registry.

* Update __init__.py

* Update ticker.py

* Bump version to 0.11.1

* Bump version to 0.11.2

* Release v0.11.3 (#50)

* Update manager.py

* Bump version to 0.11.3

* Release v0.11.4 (#51)

* Update manager.py

* Bump version to 0.11.3

* Bump version to 0.11.4

* Update requirements.txt

* Bump version to 0.11.5

* Add cron scheduler monitoring and metrics

Wire cron-related observability into the scheduler: invoke monitor hooks from MessageScheduler and CronTicker for cron register/pause/resume/cancel events, ticker ticks, materialized fires, and missed/skipped fire counts. Extend KasprMonitor with per-partition counters and sampling (registry size) and add corresponding Prometheus metrics (counters and gauges) in PrometheusMonitor, guarded by scheduler and cron feature flags.

* Bump version to 0.11.6

* Update manager.py

* Guard cron registry; disable cron by default

Wrap access to self.app.scheduler.cron_registry in a try/except (KeyError, AttributeError) and return early if the registry is absent to avoid runtime errors. Also change SCHEDULER_CRON_ENABLED default to False so cron scheduling is opt-in rather than enabled by default.

* Bump version to 0.11.7

* Merge webview routes

* Bump version to 0.11.8

* Propagate cause metadata in error responses

Enhanced `KasprProcessingError.to_dict()` to include the error message, optional raw cause object, and structured cause metadata (`status_code`, `code`, `details`, `message`) while keeping `cause` as a string for compatibility. It now also attempts to capture `cause_response` via `to_response()`. Updated webview error response building to use this richer payload: defaulting status code from cause metadata and response body from `cause_response` when custom selector functions are not provided.

* Bump version to 0.11.10

* Add pass-through mode for topic sends

Introduce a `pass_through` option on topic send specs so `TopicOutSpec.send()` can return the original value after publishing, and when `ack` is enabled, return `(value, metadata)`. Wire the new flag into the schema defaults and add coverage for default behavior, pass-through behavior, ack + pass-through output, error propagation, and a full webview processor pipeline case to ensure response objects are preserved through topic send operations.

* Bump version to 0.11.11

* Release v0.11.12 (#61)

* Inject table refs into task processor ops

Pass each operation’s injected table refs into `operator.process()` for both the initial pipeline call and subsequent stages. This fixes task pipelines where operators expect table arguments, and adds regression tests to confirm table injection works for first-step operators and later operators that also receive prior values.

* Bump version to 0.11.12

v0.11.11

Toggle v0.11.11's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Release v0.11.11 (#60) (#61)

* Release v0.11.10 (#58)

* Release v0.11.8 (#56)

* Release v0.11.7 (#55)

* Release v0.10.6 (#46)

* Pause checkpoints until in-flight ops finish

Prevent checkpoints from advancing while deliveries/removals are still in-flight. Add _pending_delivery_count and _pending_removal_count to Dispatcher/Janitor, incrementing when items are queued and decrementing on ack, and require these counters (and _unacked_deliveries being empty) before updating periodic checkpoints to avoid losing or duplicating work during rebalances. Also wait for dispatchers/janitors to drain in MessageScheduler.on_partitions_revoked before flushing checkpoints. Bump package version to 0.10.6dev.

* Bump version and clear partition metrics on revoke

Bump package version to 0.10.6dev2.

In the Prometheus monitor, clear partition-level gauge metrics when a dispatcher or janitor is revoked (remove last_location_time, last_location_seq, location_lag, and active_deliveries/active_removals) so stale values are no longer reported. Also fix janitor revoke to use janitor_info labels instead of dispatcher_info.

* Add can_distribute event and rebalance timeout

* Bump to 0.10.6dev4; drop revocation wait

* Wait for in-flight work on partition revocation

Bump package version to 0.10.6dev5 and enhance MessageScheduler.on_partitions_revoked to wait for any in-flight deliveries/removals by awaiting wait_empty_dispatchers_and_janitors() with a 10s timeout. Logs a warning on timeout, then proceeds to flush checkpoints and stop/revoke dispatchers and janitors.

* Bump version to 0.10.6

* Add cron ticker and cron registry support

Introduce cron-based scheduling support: add a CronTicker service, cron registry table and related types, settings, and utils. New kaspr/scheduler/ticker.py implements a per-partition CronTicker that pre-materializes upcoming cron fires into the timetable; manager integration creates/assigns/revokes tickers and exposes pause/resume behavior. MessageScheduler now handles CRON_ADD/CRON_CANCEL/CRON_PAUSE/CRON_RESUME actions (and routes cron requests to the actions topic), stores cron definitions in a cron-registry table, and cancels or materializes fired entries as needed. Utilities added in scheduler/utils.py: validate_cron_expr, compute_next_fire, compute_fires_in_window, cron_min_interval (uses croniter). New type kaspr/types/ticker.py and settings entries to control enabling, tick interval, buffer and minimum interval. Safety checks include cron expression validation and enforcement of a minimum allowed interval before registering a cron.

* Add cron due-index and ticker recovery

Introduce a time-bucketed cron due-index to avoid scanning the entire cron registry on each tick and add recovery/catch-up logic for missed cron fires. Key changes:

- Scheduler manager: add prepare_cron_due_index, expose cron_due_index, gate cron-related wiring/actions on scheduler_cron_enabled, and update the due-index on cron add/pause/resume/cancel.
- CronTicker: switch materialization to scan the due-index by minute-bucket (prefix_scan), add catch-up for missed fires on activation, and re-index crons to their next fire. New helpers collect and process due entries and materialize fires efficiently.
- Utils/types: add due_index_key and due_index_prefix helpers; extend KasprTableT with prefix_scan and items_for_partition and implement KasprTable.items_for_partition.
- Settings: add SCHEDULER_CRON_RECOVERY_LOOKBACK_SECONDS, increase default tick buffer, and add validation ensuring buffer/tick/min-interval invariants.
- Bump twm-faust requirement patch version.

These changes make cron tick cost proportional to due crons, improve resilience on restarts, and add configuration validation to prevent misconfiguration that could miss cron fires.

* Add missed_fire_policy for cron recovery

Introduce a missed_fire_policy to control how missed cron fires are handled on recovery. The scheduler now reads an "x-scheduler-cron-missed-fire-policy" header (default "replay") and stores missed_fire_policy on cron registry entries. On resume, manager respects the policy: "replay" preserves last_fire so missed triggers are materialized, while "skip" advances last_fire to now. CronTicker._catchup_missed_fires was rewritten to scan stale due-index buckets, separate entries by policy, replay missed fires or advance skip-entries to now (via _advance_stale_entries_to_now), and then materialize the current window. Removed the SCHEDULER_CRON_RECOVERY_LOOKBACK setting and its usage; recovery now operates by scanning the due-index instead of a bounded lookback window. Added logging to indicate recovery actions and policy decisions.

* Fix cron pause/resume and materialize past fires

Clean up duplicate header constant and adjust cron scheduling behavior around creation, pause/resume, and past fires. Use entry.created_at (not last_fire) when materializing from creation, record paused_at on pause, and on resume set last_fire to the pause time for "replay" so only the paused gap is backfilled. Ensure the due-index is written from the resume time. In the ticker, materialize past fire events into the current time slot (preserving the original fire timestamp in a header) so the Dispatcher—which only scans forward—will pick them up, update timetable locations accordingly, and set last_fire when updating the registry.

* Update __init__.py

* Release v0.11.0 (#47)

* Add cron ticker and cron registry support

Introduce cron-based scheduling support: add a CronTicker service, cron registry table and related types, settings, and utils. New kaspr/scheduler/ticker.py implements a per-partition CronTicker that pre-materializes upcoming cron fires into the timetable; manager integration creates/assigns/revokes tickers and exposes pause/resume behavior. MessageScheduler now handles CRON_ADD/CRON_CANCEL/CRON_PAUSE/CRON_RESUME actions (and routes cron requests to the actions topic), stores cron definitions in a cron-registry table, and cancels or materializes fired entries as needed. Utilities added in scheduler/utils.py: validate_cron_expr, compute_next_fire, compute_fires_in_window, cron_min_interval (uses croniter). New type kaspr/types/ticker.py and settings entries to control enabling, tick interval, buffer and minimum interval. Safety checks include cron expression validation and enforcement of a minimum allowed interval before registering a cron.

* Add cron due-index and ticker recovery

Introduce a time-bucketed cron due-index to avoid scanning the entire cron registry on each tick and add recovery/catch-up logic for missed cron fires. Key changes:

- Scheduler manager: add prepare_cron_due_index, expose cron_due_index, gate cron-related wiring/actions on scheduler_cron_enabled, and update the due-index on cron add/pause/resume/cancel.
- CronTicker: switch materialization to scan the due-index by minute-bucket (prefix_scan), add catch-up for missed fires on activation, and re-index crons to their next fire. New helpers collect and process due entries and materialize fires efficiently.
- Utils/types: add due_index_key and due_index_prefix helpers; extend KasprTableT with prefix_scan and items_for_partition and implement KasprTable.items_for_partition.
- Settings: add SCHEDULER_CRON_RECOVERY_LOOKBACK_SECONDS, increase default tick buffer, and add validation ensuring buffer/tick/min-interval invariants.
- Bump twm-faust requirement patch version.

These changes make cron tick cost proportional to due crons, improve resilience on restarts, and add configuration validation to prevent misconfiguration that could miss cron fires.

* Add missed_fire_policy for cron recovery

Introduce a missed_fire_policy to control how missed cron fires are handled on recovery. The scheduler now reads an "x-scheduler-cron-missed-fire-policy" header (default "replay") and stores missed_fire_policy on cron registry entries. On resume, manager respects the policy: "replay" preserves last_fire so missed triggers are materialized, while "skip" advances last_fire to now. CronTicker._catchup_missed_fires was rewritten to scan stale due-index buckets, separate entries by policy, replay missed fires or advance skip-entries to now (via _advance_stale_entries_to_now), and then materialize the current window. Removed the SCHEDULER_CRON_RECOVERY_LOOKBACK setting and its usage; recovery now operates by scanning the due-index instead of a bounded lookback window. Added logging to indicate recovery actions and policy decisions.

* Fix cron pause/resume and materialize past fires

Clean up duplicate header constant and adjust cron scheduling behavior around creation, pause/resume, and past fires. Use entry.created_at (not last_fire) when materializing from creation, record paused_at on pause, and on resume set last_fire to the pause time for "replay" so only the paused gap is backfilled. Ensure the due-index is written from the resume time. In the ticker, materialize past fire events into the current time slot (preserving the original fire timestamp in a header) so the Dispatcher—which only scans forward—will pick them up, update timetable locations accordingly, and set last_fire when updating the registry.

* Update __init__.py

* Update ticker.py

* Bump version to 0.11.1

* Bump version to 0.11.2

* Release v0.11.5 (#52)

* Release v0.10.6 (#46)

* Pause checkpoints until in-flight ops finish

Prevent checkpoints from advancing while deliveries/removals are still in-flight. Add _pending_delivery_count and _pending_removal_count to Dispatcher/Janitor, incrementing when items are queued and decrementing on ack, and require these counters (and _unacked_deliveries being empty) before updating periodic checkpoints to avoid losing or duplicating work during rebalances. Also wait for dispatchers/janitors to drain in MessageScheduler.on_partitions_revoked before flushing checkpoints. Bump package version to 0.10.6dev.

* Bump version and clear partition metrics on revoke

Bump package version to 0.10.6dev2.

In the Prometheus monitor, clear partition-level gauge metrics when a dispatcher or janitor is revoked (remove last_location_time, last_location_seq, location_lag, and active_deliveries/active_removals) so stale values are no longer reported. Also fix janitor revoke to use janitor_info labels instead of dispatcher_info.

* Add can_distribute event and rebalance timeout

* Bump to 0.10.6dev4; drop revocation wait

* Wait for in-flight work on partition revocation

Bump package version to 0.10.6dev5 and enhance MessageScheduler.on_partitions_revoked to wait for any in-flight deliveries/removals by awaiting wait_empty_dispatchers_and_janitors() with a 10s timeout. Logs a warning on timeout, then proceeds to flush checkpoints and stop/revoke dispatchers and janitors.

* Bump version to 0.10.6

* Release v0.11.0 (#47)

* Add cron ticker and cron registry support

Introduce cron-based scheduling support: add a CronTicker service, cron registry table and related types, settings, and utils. New kaspr/scheduler/ticker.py implements a per-partition CronTicker that pre-materializes upcoming cron fires into the timetable; manager integration creates/assigns/revokes tickers and exposes pause/resume behavior. MessageScheduler now handles CRON_ADD/CRON_CANCEL/CRON_PAUSE/CRON_RESUME actions (and routes cron requests to the actions topic), stores cron definitions in a cron-registry table, and cancels or materializes fired entries as needed. Utilities added in scheduler/utils.py: validate_cron_expr, compute_next_fire, compute_fires_in_window, cron_min_interval (uses croniter). New type kaspr/types/ticker.py and settings entries to control enabling, tick interval, buffer and minimum interval. Safety checks include cron expression validation and enforcement of a minimum allowed interval before registering a cron.

* Add cron due-index and ticker recovery

Introduce a time-bucketed cron due-index to avoid scanning the entire cron registry on each tick and add recovery/catch-up logic for missed cron fires. Key changes:

- Scheduler manager: add prepare_cron_due_index, expose cron_due_index, gate cron-related wiring/actions on scheduler_cron_enabled, and update the due-index on cron add/pause/resume/cancel.
- CronTicker: switch materialization to scan the due-index by minute-bucket (prefix_scan), add catch-up for missed fires on activation, and re-index crons to their next fire. New helpers collect and process due entries and materialize fires efficiently.
- Utils/types: add due_index_key and due_index_prefix helpers; extend KasprTableT with prefix_scan and items_for_partition and implement KasprTable.items_for_partition.
- Settings: add SCHEDULER_CRON_RECOVERY_LOOKBACK_SECONDS, increase default tick buffer, and add validation ensuring buffer/tick/min-interval invariants.
- Bump twm-faust requirement patch version.

These changes make cron tick cost proportional to due crons, improve resilience on restarts, and add configuration validation to prevent misconfiguration that could miss cron fires.

* Add missed_fire_policy for cron recovery

Introduce a missed_fire_policy to control how missed cron fires are handled on recovery. The scheduler now reads an "x-scheduler-cron-missed-fire-policy" header (default "replay") and stores missed_fire_policy on cron registry entries. On resume, manager respects the policy: "replay" preserves last_fire so missed triggers are materialized, while "skip" advances last_fire to now. CronTicker._catchup_missed_fires was rewritten to scan stale due-index buckets, separate entries by policy, replay missed fires or advance skip-entries to now (via _advance_stale_entries_to_now), and then materialize the current window. Removed the SCHEDULER_CRON_RECOVERY_LOOKBACK setting and its usage; recovery now operates by scanning the due-index instead of a bounded lookback window. Added logging to indicate recovery actions and policy decisions.

* Fix cron pause/resume and materialize past fires

Clean up duplicate header constant and adjust cron scheduling behavior around creation, pause/resume, and past fires. Use entry.created_at (not last_fire) when materializing from creation, record paused_at on pause, and on resume set last_fire to the pause time for "replay" so only the paused gap is backfilled. Ensure the due-index is written from the resume time. In the ticker, materialize past fire events into the current time slot (preserving the original fire timestamp in a header) so the Dispatcher—which only scans forward—will pick them up, update timetable locations accordingly, and set last_fire when updating the registry.

* Update __init__.py

* Release v0.11.2 (#49)

* Add cron ticker and cron registry support

Introduce cron-based scheduling support: add a CronTicker service, cron registry table and related types, settings, and utils. New kaspr/scheduler/ticker.py implements a per-partition CronTicker that pre-materializes upcoming cron fires into the timetable; manager integration creates/assigns/revokes tickers and exposes pause/resume behavior. MessageScheduler now handles CRON_ADD/CRON_CANCEL/CRON_PAUSE/CRON_RESUME actions (and routes cron requests to the actions topic), stores cron definitions in a cron-registry table, and cancels or materializes fired entries as needed. Utilities added in scheduler/utils.py: validate_cron_expr, compute_next_fire, compute_fires_in_window, cron_min_interval (uses croniter). New type kaspr/types/ticker.py and settings entries to control enabling, tick interval, buffer and minimum interval. Safety checks include cron expression validation and enforcement of a minimum allowed interval before registering a cron.

* Add cron due-index and ticker recovery

Introduce a time-bucketed cron due-index to avoid scanning the entire cron registry on each tick and add recovery/catch-up logic for missed cron fires. Key changes:

- Scheduler manager: add prepare_cron_due_index, expose cron_due_index, gate cron-related wiring/actions on scheduler_cron_enabled, and update the due-index on cron add/pause/resume/cancel.
- CronTicker: switch materialization to scan the due-index by minute-bucket (prefix_scan), add catch-up for missed fires on activation, and re-index crons to their next fire. New helpers collect and process due entries and materialize fires efficiently.
- Utils/types: add due_index_key and due_index_prefix helpers; extend KasprTableT with prefix_scan and items_for_partition and implement KasprTable.items_for_partition.
- Settings: add SCHEDULER_CRON_RECOVERY_LOOKBACK_SECONDS, increase default tick buffer, and add validation ensuring buffer/tick/min-interval invariants.
- Bump twm-faust requirement patch version.

These changes make cron tick cost proportional to due crons, improve resilience on restarts, and add configuration validation to prevent misconfiguration that could miss cron fires.

* Add missed_fire_policy for cron recovery

Introduce a missed_fire_policy to control how missed cron fires are handled on recovery. The scheduler now reads an "x-scheduler-cron-missed-fire-policy" header (default "replay") and stores missed_fire_policy on cron registry entries. On resume, manager respects the policy: "replay" preserves last_fire so missed triggers are materialized, while "skip" advances last_fire to now. CronTicker._catchup_missed_fires was rewritten to scan stale due-index buckets, separate entries by policy, replay missed fires or advance skip-entries to now (via _advance_stale_entries_to_now), and then materialize the current window. Removed the SCHEDULER_CRON_RECOVERY_LOOKBACK setting and its usage; recovery now operates by scanning the due-index instead of a bounded lookback window. Added logging to indicate recovery actions and policy decisions.

* Fix cron pause/resume and materialize past fires

Clean up duplicate header constant and adjust cron scheduling behavior around creation, pause/resume, and past fires. Use entry.created_at (not last_fire) when materializing from creation, record paused_at on pause, and on resume set last_fire to the pause time for "replay" so only the paused gap is backfilled. Ensure the due-index is written from the resume time. In the ticker, materialize past fire events into the current time slot (preserving the original fire timestamp in a header) so the Dispatcher—which only scans forward—will pick them up, update timetable locations accordingly, and set last_fire when updating the registry.

* Update __init__.py

* Update ticker.py

* Bump version to 0.11.1

* Bump version to 0.11.2

* Release v0.11.3 (#50)

* Update manager.py

* Bump version to 0.11.3

* Release v0.11.4 (#51)

* Update manager.py

* Bump version to 0.11.3

* Bump version to 0.11.4

* Update requirements.txt

* Bump version to 0.11.5

* Add cron scheduler monitoring and metrics

Wire cron-related observability into the scheduler: invoke monitor hooks from MessageScheduler and CronTicker for cron register/pause/resume/cancel events, ticker ticks, materialized fires, and missed/skipped fire counts. Extend KasprMonitor with per-partition counters and sampling (registry size) and add corresponding Prometheus metrics (counters and gauges) in PrometheusMonitor, guarded by scheduler and cron feature flags.

* Bump version to 0.11.6

* Update manager.py

* Guard cron registry; disable cron by default

Wrap access to self.app.scheduler.cron_registry in a try/except (KeyError, AttributeError) and return early if the registry is absent to avoid runtime errors. Also change SCHEDULER_CRON_ENABLED default to False so cron scheduling is opt-in rather than enabled by default.

* Bump version to 0.11.7

* Merge webview routes

* Bump version to 0.11.8

* Propagate cause metadata in error responses

Enhanced `KasprProcessingError.to_dict()` to include the error message, optional raw cause object, and structured cause metadata (`status_code`, `code`, `details`, `message`) while keeping `cause` as a string for compatibility. It now also attempts to capture `cause_response` via `to_response()`. Updated webview error response building to use this richer payload: defaulting status code from cause metadata and response body from `cause_response` when custom selector functions are not provided.

* Bump version to 0.11.10

* Add pass-through mode for topic sends

Introduce a `pass_through` option on topic send specs so `TopicOutSpec.send()` can return the original value after publishing, and when `ack` is enabled, return `(value, metadata)`. Wire the new flag into the schema defaults and add coverage for default behavior, pass-through behavior, ack + pass-through output, error propagation, and a full webview processor pipeline case to ensure response objects are preserved through topic send operations.

* Bump version to 0.11.11