Skip to content

refactor(run-store,webapp,run-engine): route Postgres TaskRun reads through the run store#3990

Draft
d-cs wants to merge 11 commits into
run-store-write-adapterfrom
runstore-read-path
Draft

refactor(run-store,webapp,run-engine): route Postgres TaskRun reads through the run store#3990
d-cs wants to merge 11 commits into
run-store-write-adapterfrom
runstore-read-path

Conversation

@d-cs

@d-cs d-cs commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds read methods to RunStore (findRun, findRunOrThrow, findRuns) and routes every Postgres read of TaskRun through them, mirroring how writes already go through the store. Behavior-preserving: each relocated read keeps its exact query, field selection, and database client (writer, replica, or transaction). This lets TaskRun reads be retargeted to a different backing store later without touching call sites.

Stacked on #3981 (the write adapter); that PR is the base of this one.

Scope

In scope: the run engine, webapp services, presenters, and route loaders. Three reads that pulled TaskRun in through a parent model's relation include (alert delivery, batch results, attempt-dependency cancellation) are decomposed to fetch the run(s) through the store and stitch them back, since a relation include would not follow TaskRun to a new table.

Left reading the existing table (out of scope): the legacy MarQS paths, the legacy trigger idempotency read, and one raw-SQL recovery script (commented for revisiting at cutover).

Notes

Reads default to the read replica; callers pass the writer or a transaction client wherever the original read did, so writer-vs-replica behavior is unchanged.

d-cs added 9 commits June 18, 2026 14:47
Add findRun, findRunOrThrow and findRuns to RunStore, mirroring the
existing write methods. They pass where/select/include through the same
Prisma generics and default to the read replica, while letting the caller
pass the writer or a transaction client when needed. This lets Postgres
reads of TaskRun be routed through the store the same way writes already
are. Additive only; no call sites change yet.
Add a no-args overload to findRun, findRunOrThrow and findRuns that
returns the whole TaskRun row, for callers that read a run without a
select or include.
Relocate the direct TaskRun reads in the engine and its systems to the
RunStore read methods, preserving the exact client (writer, replica, or
transaction) at each site. Behavior-preserving; the engine test suite is
unchanged.
…tore

Relocate the direct TaskRun reads in webapp services, run-engine concerns,
realtime, mollifier and metadata to the RunStore read methods, preserving
the exact client (writer, replica, or transaction) at each site. The run
hydrator now receives the store by injection. Behavior-preserving.
Relocate the dashboard presenter TaskRun reads to the RunStore read
methods, preserving the exact client per site. Behavior-preserving.
…store

Relocate the route and loader TaskRun reads to the RunStore read methods,
preserving the exact client per site, including the replica-resolve then
writer-recheck realtime paths. Behavior-preserving.
…store

Decompose the three reads that pulled TaskRun in through a parent model's
relation include (alert, batch results, attempt dependencies): query the
parent without the include, hydrate the run(s) via RunStore in a single
batched read, and stitch them back. Preserves field selection, ordering,
null handling and the query client. Adds container-backed tests for the
batch-results and cancel-dependencies paths.
…tover

The recovery script joins TaskRunExecutionSnapshot to TaskRun in raw SQL, so
it is the one TaskRun read not routed through the run store. Add a note to
revisit it at table cutover.
@changeset-bot

changeset-bot Bot commented Jun 18, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 789e107

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8f48f94b-1625-49c7-ae18-e6fa501c7f2a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch runstore-read-path

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@d-cs d-cs self-assigned this Jun 18, 2026

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

d-cs added 2 commits June 18, 2026 17:01
The new container tests import the service and presenter, which pull the
db.server singleton in through their base classes. Mock it so the tests do
not try to connect to the env database when none is reachable (the CI unit
shards), matching the existing webapp container-test pattern. The tests use
the injected testcontainer prisma for all reads.
Importing the service pulls the cancel chain, which eagerly initializes the
concurrency tracker singleton and requires REDIS_HOST/REDIS_PORT at import
time, so the suite cannot load in the unit-test shards without stacking
mocks. The decompose it covered is exercised by the analogous batch-results
container test and confirmed by review, so drop this one rather than mock
the tracker and cancel chain.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant