Skip to content

feat: add waitForRun(runId) API (#144)#151

Merged
coji merged 4 commits into
mainfrom
feat/wait-for-run
Mar 26, 2026
Merged

feat: add waitForRun(runId) API (#144)#151
coji merged 4 commits into
mainfrom
feat/wait-for-run

Conversation

@coji
Copy link
Copy Markdown
Owner

@coji coji commented Mar 26, 2026

Summary

  • Add waitForRun(runId, options?) method to Durably interface — waits for an existing run to complete without creating a new run
  • Extract shared waitForRunCompletion helper from triggerAndWait, eliminating code duplication
  • Add run:cancel handling to both waitForRun and triggerAndWait (throws CancelledError)
  • Add NotFoundError for non-existent run IDs
  • Add WaitForRunOptions type export

API

const run = await durably.waitForRun(runId, {
  timeout: 5000,
  onProgress: (p) => console.log(p),
  onLog: (l) => console.log(l),
})
// run.status === 'completed'
// run.output available

Test plan

  • Resolves with completed run
  • Throws on failed run
  • Throws CancelledError on cancelled run
  • Throws NotFoundError for non-existent runId
  • Timeout support
  • onProgress / onLog live callbacks (no replay)
  • Immediate resolve/reject for already-terminal runs (race condition)
  • triggerAndWait cancel handling (new behavior via shared helper)
  • Type tests for waitForRun and WaitForRunOptions
  • pnpm validate passes (format, lint, typecheck, 204 tests)

Closes #144

🤖 Generated with Claude Code

Summary by CodeRabbit

  • 新機能
    • 実行 ID を指定して実行の完了を待つ新しい waitForRun(runId, options?) メソッドを追加しました。タイムアウトや進捗・ログ受信用コールバックをサポートし、失敗・キャンセル・未検出の実行はそれぞれ適切なエラーで拒否されます。
  • 公開型
    • waitForRun のオプション型 WaitForRunOptions を公開してエクスポートしました。

)

Add waitForRun() method to Durably interface that waits for an existing
run to reach a terminal state without creating a new run. Extract shared
waitForRunCompletion helper from triggerAndWait, adding run:cancel
handling and NotFoundError support to both APIs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
durably-demo Ignored Ignored Preview Mar 26, 2026 0:24am
durably-demo-vercel-turso Ignored Ignored Preview Mar 26, 2026 0:24am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 26, 2026

Warning

Rate limit exceeded

@coji has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 11 minutes and 14 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: dfa92537-6633-4587-987c-2e45a22ae38c

📥 Commits

Reviewing files that changed from the base of the PR and between 2769365 and 575fa93.

📒 Files selected for processing (7)
  • packages/durably/docs/llms.md
  • website/.vitepress/config.ts
  • website/api/create-durably.md
  • website/api/define-job.md
  • website/api/index.md
  • website/guide/server-mode.md
  • website/public/llms.txt
📝 Walkthrough

Walkthrough

Durably インターフェースに waitForRun(runId, options?) が追加され、既存実行の完了を待機する共通ロジックが waitForRunCompletion に抽出され、triggerAndWait はこのヘルパーに委譲されるようにリファクタリングされました。関連型とエラー型が公開/利用されます。

Changes

Cohort / File(s) Summary
Core API & job logic
packages/durably/src/durably.ts, packages/durably/src/job.ts
Durably.waitForRun(runId, options?) を実装し、waitForRunCompletion ヘルパーを追加。triggerAndWait をヘルパーに委譲。CancelledError/NotFoundError を導入してエラー種別を明確化。ライブコールバック(onProgress/onLog)とタイムアウト処理を統合。
Public exports
packages/durably/src/index.ts
WaitForRunOptions を再エクスポートして公開 API に追加。
Types & tests
packages/durably/tests/node/types.test.ts, packages/durably/tests/shared/run-api.shared.ts
waitForRun の型テストを追加。統合テストを拡張し、完了/失敗/キャンセル/タイムアウト/コールバック/既完了ケース等を網羅。

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant Durably as Durably
    participant Storage as Storage
    participant EventEmitter as EventEmitter

    Client->>Durably: waitForRun(runId, options?)
    Durably->>Storage: get run status
    alt run not found
        Storage-->>Durably: null
        Durably-->>Client: Reject NotFoundError
    else run completed
        Storage-->>Durably: {status: 'completed', output}
        Durably-->>Client: Resolve completed run
    else in-flight
        Durably->>EventEmitter: subscribe (run:complete/run:fail/run:cancel)
        opt callbacks provided
            Durably->>EventEmitter: subscribe (run:progress, log:write)
        end
        EventEmitter-->>Durably: event (progress/log/complete/fail/cancel)
        alt complete
            Durably-->>Client: Resolve completed run
        else fail
            Durably-->>Client: Reject with failure
        else cancel
            Durably-->>Client: Reject CancelledError
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

Poem

🐰 新しい待ち道具を持って、
runId を見守るよ、静かに。
イベント鳴れば耳を澄まし、
完了の音で跳ねて知らせる。
小さなニンジンで祝杯を。

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add waitForRun(runId) API (#144)' clearly and concisely describes the main change — adding a new waitForRun method to the public API.
Linked Issues check ✅ Passed The PR implementation fully meets all linked issue #144 requirements: adds waitForRun(runId, options?), returns completed Run with output, throws NotFoundError for missing runs, throws CancelledError for cancelled runs, supports timeout/onProgress/onLog options, and includes comprehensive test coverage.
Out of Scope Changes check ✅ Passed All changes are directly aligned with #144 objectives: new waitForRun API, extracted waitForRunCompletion helper to eliminate duplication, run:cancel handling, error types, and type exports. No extraneous modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/wait-for-run

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/durably/src/job.ts`:
- Around line 265-383: The function waitForRunCompletion currently only listens
to the local eventEmitter and will miss terminal updates made by other
instances; add a fallback polling path that repeatedly calls
storage.getRun(runId) until the run reaches a terminal state
(completed/failed/cancelled) so cross-process completions are observed.
Concretely, inside waitForRunCompletion (the function shown), start a
setInterval (use a small default like 500ms or options.pollInterval if provided)
after the initial storage.getRun() check, have the interval call
storage.getRun(runId) and on each result apply the same terminal-state logic
(resolve with run, reject with Error/CancelledError/NotFoundError), ensure the
interval id is cleared in cleanup and that polling stops once resolved is true,
and keep existing eventEmitter handlers (or remove polling if a DB-backed
subscription is later added). Ensure timeout handling (options.timeout) still
cancels polling via cleanup.

In `@packages/durably/tests/shared/run-api.shared.ts`:
- Around line 693-706: The live-callback test is timing-dependent because
waitForRun() does not replay past events: move the call to d.waitForRun(run.id,
{...}) (with onProgress/onLog handlers collecting into progressUpdates/logs) to
run before d.start(), so the subscription is established before the worker is
started (the code invoking d.start() and d.jobs.job.trigger({}) should be
ordered so waitForRun is initiated prior to d.start()).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 27e651ff-1e43-45fe-be1c-8dd9de1ca0c7

📥 Commits

Reviewing files that changed from the base of the PR and between ba1eb1e and f4fad82.

📒 Files selected for processing (5)
  • packages/durably/src/durably.ts
  • packages/durably/src/index.ts
  • packages/durably/src/job.ts
  • packages/durably/tests/node/types.test.ts
  • packages/durably/tests/shared/run-api.shared.ts

Comment thread packages/durably/src/job.ts
Comment thread packages/durably/tests/shared/run-api.shared.ts
Start waitForRun subscription before worker to ensure all live
progress/log events are captured reliably.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add usage examples, WaitForRunOptions type definition, and update
TriggerAndWaitOptions to show the new extends relationship.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- create-durably.md: new waitForRun() section with signature and options
- define-job.md: tip comparing triggerAndWait vs waitForRun
- index.md: cheat sheet example and instance methods table
- server-mode.md: "Waiting for Existing Runs" guide section
- config.ts: sidebar entry for waitForRun

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coji coji merged commit 71130d4 into main Mar 26, 2026
5 checks passed
@coji coji deleted the feat/wait-for-run branch March 26, 2026 13:02
@coji coji mentioned this pull request Mar 29, 2026
4 tasks
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.

feat: waitForRun(runId) API to observe existing run completion

1 participant