fix: add last active column to step concurrency table#4286
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Benchmark resultsCompared against |
| v1_step_concurrency strategy ON strategy.workflow_id = cs.workflow_id AND strategy.workflow_version_id = cs.workflow_version_id AND strategy.id = cs.strategy_id | ||
| WHERE | ||
| strategy.is_active = FALSE | ||
| OR strategy.last_active < NOW() - INTERVAL '1 hour' |
There was a problem hiding this comment.
We also want to update the v1_step_concurrency when the last_active has been stale for more than an hour - hence a very hot strat will only update the last_active every hour rather than every time.
There was a problem hiding this comment.
Pull request overview
This PR introduces a last_active_at timestamp on v1_step_concurrency to better track recent strategy activity (mirroring v1_queue) and uses it to gate stale strategy deactivation, reducing unnecessary cold-start churn.
Changes:
- Add
last_active_attov1_step_concurrency(schema + migration) and include it in sqlc-generated models/queries. - Update the concurrency-slot insert trigger to refresh
last_active_atwhen strategies are reactivated / periodically (throttled) on activity. - Re-enable the periodic “deactivate stale step concurrency” controller operation and update the deactivation query to only deactivate strategies inactive for >1 day.
Reviewed changes
Copilot reviewed 3 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| sql/schema/v1-core.sql | Adds last_active_at to v1_step_concurrency and refreshes it in the slot-insert trigger logic. |
| cmd/hatchet-migrate/migrate/migrations/20260629110253_v1_0_120.sql | Migration to add last_active_at and update the trigger function for existing installs. |
| pkg/repository/sqlcv1/models.go | Extends V1StepConcurrency with LastActiveAt. |
| pkg/repository/sqlcv1/workflows.sql.go | Updates RETURNING columns to include last_active_at for step concurrency creation flows. |
| pkg/repository/sqlcv1/concurrency.sql | Adds last_active_at gating to stale deactivation query. |
| pkg/repository/sqlcv1/concurrency.sql.go | Regenerated sqlc output reflecting the updated stale deactivation and selects. |
| internal/services/controllers/task/controller.go | Re-enables the periodic stale step-concurrency deactivation operation pool. |
| internal/services/controllers/task/deactivate_stale_step_concurrency.go | Implements the operation method that invokes the repository deactivation query. |
| pkg/scheduling/v1/tenant_manager.go | Threads ctx into concurrency-strategy updates (currently unused in the methods). |
| pkg/scheduling/v1/concurrency.go | Minor formatting-only change. |
Files not reviewed (3)
- pkg/repository/sqlcv1/concurrency.sql.go: Generated file
- pkg/repository/sqlcv1/models.go: Generated file
- pkg/repository/sqlcv1/workflows.sql.go: Generated file
Comments suppressed due to low confidence (1)
sql/schema/v1-core.sql:913
- The trigger’s inactive_strategies CTE can include the same v1_step_concurrency row multiple times when a single INSERT statement creates multiple slots for the same strategy (new_table has duplicates). Deduplicating before FOR UPDATE avoids extra join work/locking overhead and keeps the UPDATE deterministic.
WITH inactive_strategies AS (
SELECT
strategy.*
FROM
new_table cs
| -- last_active_at is refreshed whenever a slot is created for this strategy. The stale-deactivation | ||
| -- sweep only deactivates a strategy once it has had no slots AND last_active_at is over a day old, so | ||
| -- a strategy used periodically is never deactivated (and so never pays a cold start). Mirrors how | ||
| -- v1_queue.last_active gates the 1-day queue activity window. | ||
| last_active_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, |
| WITH inactive_strategies AS ( | ||
| SELECT | ||
| strategy.* | ||
| FROM | ||
| new_table cs | ||
| JOIN | ||
| v1_step_concurrency strategy ON strategy.workflow_id = cs.workflow_id AND strategy.workflow_version_id = cs.workflow_version_id AND strategy.id = cs.strategy_id | ||
| WHERE | ||
| strategy.is_active = FALSE | ||
| OR strategy.last_active_at < NOW() - INTERVAL '1 hour' | ||
| ORDER BY | ||
| strategy.id | ||
| FOR UPDATE | ||
| ) |
| FROM v1_step_concurrency sc | ||
| WHERE sc.tenant_id = @tenantId::UUID | ||
| AND sc.is_active = TRUE | ||
| AND sc.last_active_at < NOW() - INTERVAL '1 day' | ||
| AND NOT EXISTS ( |
| WHERE sc.tenant_id = @tenantId::UUID | ||
| AND sc.is_active = TRUE | ||
| AND sc.last_active_at < NOW() - INTERVAL '1 day' | ||
| AND NOT EXISTS ( |
|
|
Description
This PR adds a new
last_activecolumn tov1_step_concurrencyto mirrorv1_queueType of change
Checklist
Changes have been:
🤖 AI Disclosure