honcho/tests
Rajat Ahuja 26be90f60d fix(deriver): bound the shutdown drain and release claims before exit
Shutdown waited on asyncio.gather(*active_tasks) with no timeout, and released
work-unit claims only via the finally in initialize(). Both assume the process
gets as long as it needs.

It does not. A platform can terminate the process on a budget shorter than a
single work unit takes -- a deriver LLM call alone can run for tens of seconds
-- and when that budget expires the process is killed outright. The unbounded
wait is then still in progress, initialize() never returns, its finally never
runs, and the claims are left held. The work is not lost, but nothing may touch
it until cleanup_stale_work_units notices, which takes
STALE_SESSION_TIMEOUT_MINUTES plus a jittered poll interval.

So shutdown is a race to hand the claims back, not an opportunity to finish the
work. Two changes:

Drain is bounded by SHUTDOWN_DRAIN_TIMEOUT_SECONDS (default 8). Work that fits
in the budget still completes; work that does not is cancelled rather than
waited on, since the work is reclaimable and the remaining budget is not.

cleanup() is called at the end of shutdown() rather than relying on the finally
in initialize(). Claims are given up while the process is still alive, so
another worker repicks the work on its next poll instead of waiting out the
stale sweep. cleanup() clears worker_ownership, so the existing call in the
finally becomes a no-op and the ordering is idempotent.

The drain deliberately runs before the release rather than after. Releasing
first would leave a window in which a task that completes during shutdown has
already had its claim taken by another worker, and the same queue items get
derived twice. Cancelling first and releasing after keeps that window closed,
and both steps fit inside a short budget.

Cancelling also keeps the error reporting honest without special-casing it.
asyncio.CancelledError derives from BaseException rather than Exception, so an
abandoned task passes straight through the `except Exception` handlers that
report to Sentry. Shutdown stops generating spurious errors on its own, while a
task that genuinely fails during the drain, or a cleanup() that cannot reach the
database, still reports as it should.

Tests cover a task that outlives the budget being abandoned with cleanup still
awaited, and a task that fits in the budget still finishing.
2026-08-26 14:53:38 -04:00
..
alembic feat: make session_name nullable for documents and update related SDKs (#347) 2026-01-26 13:33:11 -05:00
bench telemetry: zero-initialize bounded-label metrics so an absent series means a broken scrape (#927) 2026-08-20 10:24:49 -04:00
crud fix(scopes): scope observer sessions in SQL instead of a fetched name list (#1065) 2026-08-25 13:24:31 -04:00
deriver fix(deriver): bound the shutdown drain and release claims before exit 2026-08-26 14:53:38 -04:00
dialectic Scopes Phase 2b: `scope` option on chat, representation, context, and search (#897) 2026-08-12 18:34:55 -04:00
dreamer Scopes Phase 2a: scope-kind peers, guardrails, and scopes CRUD routes (#884) 2026-08-12 16:21:40 -04:00
integration feat: defer embedding messages (#704) 2026-06-11 10:31:04 -04:00
live_llm fix(openai): fix content normalization in openai backend history adapter (#1064) 2026-08-26 12:14:32 -04:00
llm fix(openai): fix content normalization in openai backend history adapter (#1064) 2026-08-26 12:14:32 -04:00
reconciler telemetry: zero-initialize bounded-label metrics so an absent series means a broken scrape (#927) 2026-08-20 10:24:49 -04:00
routes feat: Add workspace-level chat (#931) 2026-08-24 15:54:23 -04:00
scripts feat: add new cloudevents for api routes (#637) 2026-05-20 18:25:30 -04:00
sdk Scopes SDK Changes (#1030) 2026-08-19 10:48:29 -04:00
sdk_typescript add read db (#773) 2026-06-10 13:28:36 -04:00
startup add read db (#773) 2026-06-10 13:28:36 -04:00
telemetry review: fix db_connections_open leak on the detach path; comment/doc polish 2026-08-24 14:37:20 -04:00
unified feat: Add workspace-level chat (#931) 2026-08-24 15:54:23 -04:00
utils fix(filter): make ne on jsonb metadata keys null-safe (#1036) 2026-08-24 09:33:08 -04:00
vector_store fix: apply session scoping to all working-representation query paths (#881) 2026-07-24 11:41:34 -04:00
webhooks Tighten Transaction Scopes (#525) 2026-04-08 11:14:50 -04:00
__init__.py Refactor clients.py to add modern features and more flexible configuration (#459) 2026-04-20 02:46:37 -04:00
conftest.py fix(scopes): scope observer sessions in SQL instead of a fetched name list (#1065) 2026-08-25 13:24:31 -04:00
test_advanced_filters.py fix(filter): make ne on jsonb metadata keys null-safe (#1036) 2026-08-24 09:33:08 -04:00
test_cache_key_namespace.py perf(cache): hash-tag the cache namespace so an instance uses one shard (#1058) 2026-08-25 12:34:42 -04:00
test_cache_redaction.py Scopes Phase 2a: scope-kind peers, guardrails, and scopes CRUD routes (#884) 2026-08-12 16:21:40 -04:00
test_config.py fix(llm): support per-request provider timeouts (#832) 2026-08-04 12:43:00 -04:00
test_datetime_parsing.py Make embeddings configurable (#678) 2026-05-14 15:03:35 -04:00
test_db_resilience.py fix(deriver): increase deriver polling backoff (#1015) 2026-08-14 16:38:20 -04:00
test_dependencies.py add read db (#773) 2026-06-10 13:28:36 -04:00
test_dialectic_prompts.py fix(dialectic): revamp workspace and pair chat system prompts (#1066) 2026-08-25 12:30:06 -04:00
test_generate_jwt_script.py feat: add generate_jwt.py script for creating scoped JWTs (#757) 2026-06-09 13:49:55 -04:00
test_models_vector_dim.py feat: add new cloudevents for api routes (#637) 2026-05-20 18:25:30 -04:00
test_schema_validations.py Align API contract with DB contract for IDs (#684) 2026-05-14 16:37:39 -04:00
test_search.py fix(crud): preserve joined_at for active session peers (#1059) 2026-08-25 10:51:59 -04:00
test_security.py feat: Add workspace-level chat (#931) 2026-08-24 15:54:23 -04:00
test_session_allowlist.py fix(filter): make the filter DSL reject bad input instead of 500ing, and fix negation over unset fields (#947) 2026-08-13 10:39:19 -04:00
test_workspace_chat.py fix(dialectic): revamp workspace and pair chat system prompts (#1066) 2026-08-25 12:30:06 -04:00