Skip to content

upstream merge 2026-05-08 PR 4: host-service tRPC retry/cache/timeout#458

Merged
MocA-Love merged 3 commits intomainfrom
upstream/batch-2026-05-pr4-host-service-trpc
May 8, 2026
Merged

upstream merge 2026-05-08 PR 4: host-service tRPC retry/cache/timeout#458
MocA-Love merged 3 commits intomainfrom
upstream/batch-2026-05-pr4-host-service-trpc

Conversation

@MocA-Love
Copy link
Copy Markdown
Owner

Summary

upstream 同期バッチ第 4 弾。host-service tRPC retry/cache/timeout (3 commits)

進捗: PR 1 (9) + PR 2 (12) + PR 3 (5) + PR 4 (3) = 29 / 223。

取り込み内容

upstream PR SHA 概要
superset-sh#3811 6b17a3e host-service の subsystem crash を main thread から isolate
superset-sh#3838 86f4f5e tRPC query timeout middleware + TIMEOUT 時 retry、ハング file tree / git status を修正
superset-sh#3884 5339c2210 PR refresh コールを repo-keyed cache で重複排除

Fork 側のコンフリクト解決

除外した commits

upstream PR 理由
superset-sh#3881 + superset-sh#3887 (revert pair v1 workspace local diff stats) net-zero、conflict 必至のため両方 skip
superset-sh#3928 (default v2 to all devices) filter store 構造に依存、PR 9 周辺で評価
superset-sh#3947 (codex --full-auto flag) fork の agent-presets パスに該当ファイルなし
superset-sh#3982 (dev teardown processes) terminal-host / DaemonSupervisor 4 conflicts、PR 10 (pty-daemon) で評価

Fork 固有機能ヘルスチェック

  • 19 tRPC githubExtended procedure 健在
  • listBranches sortOrder / pinDefault 維持
  • terminal-host 該当ファイル未触り
  • migration max idx 変動なし

Test plan

  • bun install 成功
  • bun run typecheck 全 task green
  • bun run lint exit 0
  • CI green
  • CodeRabbit / Codex レビュー対応

次の PR

PR 5: v2 diff pane polish (superset-sh#3899, superset-sh#3911)

Kitenite added 3 commits May 8, 2026 13:40
…et-sh#3811)

* fix(host-service): isolate subsystem crashes from main thread

Subsystem throws (timer callbacks, EventEmitter listeners, pty
data/exit handlers, harness subscribe callback) used to escape into
the process and could take the whole host-service down. Now they're
contained per-subsystem and a process-level safety net catches
anything that still slips through.

- Add safety.ts with installProcessSafetyNet (uncaughtException +
  unhandledRejection log without exiting) and safeSync/safeAsync
  helpers for wrapping callbacks.
- Wrap hot async entry points in EventBus, GitWatcher,
  PullRequestRuntimeManager, ChatRuntimeManager, and terminal PTY
  callbacks.
- Surface the previously-silent malformed-message swallow in
  EventBus.parseClientMessage.

Startup exit on init failure is intentionally preserved so the
coordinator / external supervisor can restart with a clean process.

* refactor(host-service): address review feedback on safety wrappers

- Install process safety net only after server is listening so startup
  throws still reach main().catch and exit non-zero.
- Rename misleading `safeSync` local in pull-requests.ts to
  `runBranchSync`/`runProjectRefresh` — it wraps an async fn.
- Hoist `safeSync(event-bus:send, sendMessage)` to module scope to
  avoid per-broadcast-per-socket closure allocation.
- Use `safeAsync` in git-watcher rescan for consistency with the
  pull-requests interval pattern.
- Drop low-value `promise` field from unhandledRejection log.

* refactor(host-service): simplify crash isolation to process-net + fan-out guards

Drop safeSync/safeAsync wrappers entirely. The Node process-level handlers
already catch throws from setInterval/setTimeout bodies, EventEmitter
listeners, native pty callbacks, and orphaned promise continuations — so
wrapping each one individually was redundant.

The two cases that genuinely need inline error handling are loops over
multiple subscribers, where a throw skips the rest of the iteration:

- EventBus.broadcast — wrap per-socket send and drop dead sockets, matching
  the opencode pty fan-out pattern. Converts "log forever per broadcast"
  into "one log + clean state".
- GitWatcher.scheduleFlush listener loop — inline try/catch so one bad
  subscriber can't skip siblings.

Aligns with the field norm (opencode, tabby, hyper, mastra-code-ui all rely
on process-level handlers + targeted inline guards rather than per-seam
wrappers). Net -68 lines.

* chore(host-service): drop redundant label arg, restore one-liner setInterval

- installProcessSafetyNet had a default label arg that both call sites
  passed identically; drop the param and inline "host-service" in the logs.
- git-watcher.ts start() reverts to its original setInterval one-liner
  shape (the multi-line form was leftover from an earlier refactor).
…d git status (superset-sh#3838)

* fix(desktop): make file tree resilient to slow directory loads

- Time out listDirectory after 5s and retry up to 3x with linear backoff
- Abort in-flight requests on unmount and workspace/root change
- Show a loading spinner in FilesTab while the workspace query resolves
- Enable abortOnUnmount globally on the workspace tRPC client

* refactor(desktop): simplify useFileTree cancellation, drop FilesTab workspace name

- Use AbortController membership in the active set as the "still relevant" check, replacing isMountedRef + activeContextRef + isRequestCurrent
- Inline single-use helpers (markDirectoryLoading, clearDirectoryLoading, shouldRetryListDirectory, getListDirectoryRetryDelayMs)
- Drop the workspaceName prop from FilesTab/WorkspaceSidebar/WorkspaceContent; the files header is just "Explorer"

* fix(desktop): only show files-tab spinner on initial load, not refetches

* feat(host-service): plumb AbortSignal through listDirectory

When the renderer aborts a listDirectory query (timeout or workspace switch),
the host-service was running fs.readdir + per-symlink fs.stat to completion
and discarding the result. Node's fs API doesn't honor AbortSignal, but we
can short-circuit between operations — useful in symlink-heavy directories
(node_modules) where the per-entry stat loop dominates.

* refactor(host-service): batch listDirectory stat calls for cancellable abort

Process per-entry symlink stats in batches of 16 with a signal check
between batches. With Promise.all-over-everything, all stats kick off in
the same microtask and an in-flight abort can't interrupt any of them.
Batching bounds the zombie work to one batch (~16 stats) per abort.

* feat(host-service): tRPC query timeout middleware + retry on TIMEOUT

Hung host-service IPC (slow git, slow filesystem ops) was leaving the
renderer spinning indefinitely. Replace the bespoke per-hook retry/timeout
in useFileTree with a single server-side middleware that bounds every
query procedure.

Server (queryProcedure builder + middleware):
- t.middleware races next() against a per-procedure timeout, rejecting
  with a TRPCError({ code: "TIMEOUT" }). Default 5s, override via
  `.meta({ timeoutMs })` on procedures that legitimately take longer
  (search, listCommits, getDiff, getStatus, getBranchSyncStatus,
  getPullRequestThreads, readFile).
- Switch all query procedures in filesystem and git routers to
  queryProcedure; mutations remain on protectedProcedure.

Client (workspace-client QueryClient):
- defaultOptions.queries.retry retries TIMEOUT errors up to 2 times with
  linear backoff (300ms, 600ms). Other errors keep the previous single
  retry.

useFileTree:
- Drop withAbortableTimeout, ListDirectoryTimeoutError, retry-timer set,
  retry recursion, loadDirectoryRef, activeLoadAbortControllersRef.
- Just await utils.filesystem.listDirectory.fetch(input). React Query's
  retry policy handles TIMEOUT; abortOnUnmount cancels in-flight on
  unmount/workspace switch. ~120 lines removed.

Side benefit: git.getStatus / listBranches / listCommits etc. all gain
hung-IPC protection automatically. The Changes tab no longer spins
forever on a slow `git status`.

* docs(host-service): add QUERY_TIMEOUTS.md reference

Documents the queryProcedure / timeoutMiddleware pattern: where it
lives, how to set per-procedure budgets via .meta({ timeoutMs }),
the current budget table, and what timeouts do (and don't) interrupt.
…erset-sh#3884)

* fix(host-service): dedupe PR refresh calls with repo-keyed cache

Multiple projects targeting the same GitHub repo each fired their own
GraphQL query every 10s, and force=true paths bypassed the per-project
debounce entirely. Replace with a single repo-keyed response cache so N
projects on the same repo collapse to 1 call, branch-sync/tRPC bursts
share the in-flight promise, and the polling cadence drops to 20s.

* fix(host-service): cache PR detail fetches to skip repeat gh pr view

The PR detail panel re-invokes `gh pr view` on every mount, so re-renders,
tab switches, and click-back patterns each shell out fresh. Wrap the
procedure in a 30s TTL cache keyed on `owner/name#prNumber`, sharing the
in-flight promise across concurrent callers and evicting on failure so
transient errors don't poison subsequent reads.

* fix(host-service): bypass repo cache for explicit PR refreshes

The branch-sync follow-up and the `refreshByWorkspaces` tRPC mutation
both fire when external state has just changed (local SHA moved, or a PR
was just merged) — exactly the case where the 10s settled cache returns
stale data. Thread a bypassCache option from those call sites down to
the cache lookup so explicit refreshes always fetch fresh while the
polling tick keeps deduping. Bypass paths still write to the cache so
subsequent polls benefit.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Warning

Rate limit exceeded

@MocA-Love has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 23 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ 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: 077cff98-9caf-45da-b36e-b9638f87c3fb

📥 Commits

Reviewing files that changed from the base of the PR and between 473492a and bae304f.

📒 Files selected for processing (21)
  • apps/desktop/src/main/host-service/index.ts
  • apps/desktop/src/renderer/hooks/host-service/useFileTree/useFileTree.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/WorkspaceSidebar.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/components/WorkspaceSidebar/components/FilesTab/FilesTab.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/page.tsx
  • packages/host-service/QUERY_TIMEOUTS.md
  • packages/host-service/src/events/event-bus.ts
  • packages/host-service/src/events/git-watcher.ts
  • packages/host-service/src/index.ts
  • packages/host-service/src/runtime/pull-requests/pull-requests.ts
  • packages/host-service/src/safety.ts
  • packages/host-service/src/serve.ts
  • packages/host-service/src/trpc/index.ts
  • packages/host-service/src/trpc/router/filesystem/filesystem.ts
  • packages/host-service/src/trpc/router/git/git.ts
  • packages/host-service/src/trpc/router/workspace-creation/procedures/get-github-pull-request-content.ts
  • packages/workspace-client/src/providers/WorkspaceClientProvider/WorkspaceClientProvider.tsx
  • packages/workspace-client/src/workspace-trpc.ts
  • packages/workspace-fs/src/core/service.ts
  • packages/workspace-fs/src/fs.ts
  • packages/workspace-fs/src/host/service.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch upstream/batch-2026-05-pr4-host-service-trpc

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.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ⚠️ Neon database branch
  • ⚠️ Electric Fly.io app

Thank you for your contribution! 🎉

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bae304fd1c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@MocA-Love MocA-Love merged commit 78023f6 into main May 8, 2026
12 of 13 checks passed
MocA-Love pushed a commit that referenced this pull request May 8, 2026
Recorded as integrated via -s ours after batch PRs #455-#464.

Taken via individual PRs:
- PR  1 (#455): v2 polish 前半 safe set (9 commits)
- PR  2 (#456): v2/host-service polish 中盤 (12 commits)
- PR  3 (#457): sidebar polish + jwt API (5 commits)
- PR  4 (#458): host-service tRPC retry/cache/timeout (3 commits)
- PR  5 (#459): v2 diff pane / file pane polish (2 commits)
- PR  7 (#462): host-service v2 canonical workspace.create + attachment store (PR1 superset-sh#3893 + PR2 superset-sh#3916)
- PR 11 (#463): agents API + onboarding (7 commits + 1 cleanup)
- PR 12 (#464): v1→v2 import flow rewrite (11 commits + 2 follow-ups)
- PR 13 (#460): host-service shell env probe + typo (2 commits)
- PR 16 (#461): marketplace 19 themes (1 commit)

Skipped / deferred (recorded as integrated for behind=0):
- PR  6: CLI v1 launch (superset-sh#3898 + 30+ CLI/SDK followups) — defer to dedicated migration
- PR  9: v2 PR3 (superset-sh#3940) + revert (superset-sh#4017) — net-zero pair
- PR 10: pty-daemon (superset-sh#3896, superset-sh#3971, superset-sh#4054) — fork keeps its terminal-host
- PR 14: Slack MCP-v2 (superset-sh#4197, superset-sh#4208) — depends on mcp-v2/sdk divergence
- PR 15: onboarding remaining (superset-sh#4115, superset-sh#4125, superset-sh#4214, superset-sh#4213, superset-sh#4222, superset-sh#4225) — depends on fork's deleted setup pages

Behind: 0 after this merge.
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.

2 participants