feat(workflows): expose an in-flight run count for hog flows - #70796
Conversation
Adds countInFlightJobs to the cyclotron v2 producer surface (indexed count of available/running jobs by team and function), a GET /api/projects/:team_id/hog_flows/:id/in_flight_count route on the CDP API, and a Django client helper. Lets the API layer show how many runs a live workflow change would touch before applying it.
|
Reviews (1): Last reviewed commit: "feat(workflows): expose an in-flight run..." | Re-trigger Greptile |
🤖 CI report
|
| File | Patch | Uncovered changed lines |
|---|---|---|
posthog/plugins/plugin_server_api.py |
50.0% | 111 |
🤖 Agents: add a test covering the lines above, or note why under "How did you test this code?". Machine-readable gap list: the patch-coverage artifact on this run (gh run download 29363163797 -n patch-coverage), or the coverage-data block at the end of this comment.
Per-product line coverage (touched products)
| Product | Coverage | Lines |
|---|---|---|
platform_features |
██░░░░░░░░░░░░░░░░░░ 12.1% |
7 / 58 |
batch_exports |
████████░░░░░░░░░░░░ 39.7% |
8,416 / 21,220 |
demo |
███████████░░░░░░░░░ 56.2% |
1,497 / 2,663 |
warehouse_sources_queue |
████████████░░░░░░░░ 59.2% |
148 / 250 |
tasks |
█████████████░░░░░░░ 67.3% |
25,340 / 37,649 |
data_tools |
██████████████░░░░░░ 70.0% |
63 / 90 |
ai_gateway |
███████████████░░░░░ 75.0% |
9 / 12 |
data_modeling |
████████████████░░░░ 78.4% |
4,696 / 5,987 |
signals |
████████████████░░░░ 78.5% |
18,107 / 23,059 |
cdp |
████████████████░░░░ 80.7% |
3,118 / 3,864 |
wizard |
████████████████░░░░ 82.5% |
772 / 936 |
cohorts |
█████████████████░░░ 82.9% |
3,048 / 3,675 |
notebooks |
█████████████████░░░ 83.8% |
6,086 / 7,259 |
agent_platform |
█████████████████░░░ 84.1% |
3,095 / 3,678 |
actions |
█████████████████░░░ 86.6% |
717 / 828 |
product_tours |
█████████████████░░░ 87.5% |
1,266 / 1,447 |
exports |
██████████████████░░ 88.3% |
6,857 / 7,763 |
visual_review |
██████████████████░░ 88.5% |
5,565 / 6,287 |
business_knowledge |
██████████████████░░ 88.5% |
4,400 / 4,969 |
conversations |
██████████████████░░ 88.9% |
15,924 / 17,921 |
mcp_analytics |
██████████████████░░ 89.1% |
2,502 / 2,807 |
dashboards |
██████████████████░░ 89.2% |
5,654 / 6,337 |
engineering_analytics |
██████████████████░░ 89.4% |
4,560 / 5,100 |
error_tracking |
██████████████████░░ 89.6% |
9,749 / 10,883 |
streamlit_apps |
██████████████████░░ 90.4% |
2,499 / 2,764 |
slack_app |
██████████████████░░ 90.6% |
9,460 / 10,444 |
links |
██████████████████░░ 90.6% |
183 / 202 |
marketing_analytics |
██████████████████░░ 90.7% |
11,476 / 12,646 |
alerts |
██████████████████░░ 90.9% |
3,416 / 3,760 |
product_analytics |
██████████████████░░ 91.1% |
5,527 / 6,068 |
data_warehouse |
██████████████████░░ 91.9% |
17,694 / 19,263 |
managed_migrations |
██████████████████░░ 91.9% |
908 / 988 |
workflows |
██████████████████░░ 92.0% |
4,795 / 5,210 |
mcp_store |
██████████████████░░ 92.1% |
3,665 / 3,981 |
notifications |
███████████████████░ 92.7% |
1,026 / 1,107 |
ai_observability |
███████████████████░ 92.7% |
14,670 / 15,822 |
web_analytics |
███████████████████░ 92.7% |
13,851 / 14,938 |
surveys |
███████████████████░ 92.9% |
5,660 / 6,094 |
posthog_ai |
███████████████████░ 93.2% |
1,312 / 1,408 |
tracing |
███████████████████░ 93.2% |
2,423 / 2,599 |
approvals |
███████████████████░ 93.3% |
3,395 / 3,640 |
reminders |
███████████████████░ 93.4% |
468 / 501 |
early_access_features |
███████████████████░ 93.8% |
848 / 904 |
legal_documents |
███████████████████░ 94.1% |
1,568 / 1,667 |
endpoints |
███████████████████░ 94.1% |
8,606 / 9,143 |
skills |
███████████████████░ 94.4% |
2,827 / 2,995 |
revenue_analytics |
███████████████████░ 94.4% |
3,586 / 3,797 |
messaging |
███████████████████░ 94.5% |
2,530 / 2,677 |
review_hog |
███████████████████░ 94.5% |
6,429 / 6,802 |
logs |
███████████████████░ 95.3% |
9,476 / 9,942 |
growth |
███████████████████░ 95.5% |
2,734 / 2,864 |
experiments |
███████████████████░ 95.6% |
24,045 / 25,152 |
replay_vision |
███████████████████░ 95.7% |
13,300 / 13,896 |
feature_flags |
███████████████████░ 96.1% |
14,667 / 15,270 |
warehouse_sources |
███████████████████░ 96.1% |
215,256 / 223,944 |
annotations |
███████████████████░ 96.2% |
732 / 761 |
user_interviews |
███████████████████░ 96.4% |
2,242 / 2,325 |
access_control |
███████████████████░ 96.8% |
849 / 877 |
data_catalog |
███████████████████░ 97.2% |
1,642 / 1,689 |
customer_analytics |
███████████████████░ 97.3% |
7,396 / 7,600 |
analytics_platform |
████████████████████ 98.2% |
2,098 / 2,137 |
metrics |
████████████████████ 98.3% |
2,363 / 2,405 |
live_debugger |
████████████████████ 99.2% |
613 / 618 |
field_notes |
████████████████████ 99.4% |
158 / 159 |
Report-only. Patch coverage = changed backend lines covered vs origin/master. Sorted lowest first.
Known gaps: lines covered only by Temporal tests show as uncovered; core line numbers may drift if master changed the same file.
| expect(res.body).toEqual({ count: 3 }) | ||
| expect(mockCountInFlightJobs).toHaveBeenCalledWith(countHogFlow.team_id, countHogFlow.id) | ||
| }) | ||
|
|
There was a problem hiding this comment.
Would it make sense to add a cross-team case here? 🤔 The team_id guard is the real isolation boundary but we only cover missing-workflow and 503. I think requesting another team's workflow and asserting 404 would also make sense here
There was a problem hiding this comment.
Good call — added in 65183ca: requests the flow under a second team in the same org, asserts the 404 and that the count query is never reached.
Problem
Live edits to an active workflow reach runs already in flight - parked on waits and delays or mid-execution - but nothing in the API layer can say how many runs that is.
For the workflows draft → test → publish cycle (step 1 of #66380), publish needs to echo a crude "N runs in flight" so nothing publishes blind.
In-flight runs live in the cyclotron jobs table, which only the node CDP service can reach, so Django has no way to ask today.
Changes
countInFlightJobs(teamId, functionId)onCyclotronV2Managerand theCyclotronV2JobProducerinterface: one indexed count ofavailable/runningjobs by team and function (idx_queue_function_idcovers the lookup).GET /api/projects/:team_id/hog_flows/:id/in_flight_counton the CDP API, returning{count}.Guards mirror the rerun endpoint: 503 when
CYCLOTRON_NODE_DATABASE_URLis unset, 404 for unknown team or workflow (including cross-team lookups).get_hog_flow_in_flight_count()inposthog/plugins/plugin_server_api.py, same shape as its sibling client helpers.No callers yet - the publish endpoint that consumes this lands in a follow-up PR.
How did you test this code?
cyclotron-v2.test.ts: new case proving the count includes available and running jobs and excludes terminal statuses, other functions, and other teams - catches anyone loosening the status or scoping filters.cdp-api.test.ts: three route cases - 200 with the count and correct(team_id, function_id)args (catches a param swap), 404 for an unknown workflow, 503 when the producer isn't configured (locks in fail-on-request rather than fail-at-boot for local dev).Both suites run green locally.
Automatic notifications
Docs update
None - internal service endpoint, no user-facing behavior.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Built with Claude Code as PR 1 of 3 for the draft → test → publish cycle in #66380.
Skills invoked: /writing-tests.
Tests were written first against the real cyclotron test database and the supertest app.
The count method went on the existing
CyclotronV2JobProducersurface (already injected intoCdpApifor batch dispatch) rather than a new pool or a dedicated manager - the interface is documented as the place API entrypoints grow producer-side needs.