Skip to content

Scope tools-read catalog refresh to the read filter - #1605

Draft
RhysSullivan wants to merge 5 commits into
mainfrom
fix/tools-sync-read-path
Draft

Scope tools-read catalog refresh to the read filter#1605
RhysSullivan wants to merge 5 commits into
mainfrom
fix/tools-sync-read-path

Conversation

@RhysSullivan

Copy link
Copy Markdown
Collaborator

A tools read refreshed every stale connection in the account before answering, sequentially — a GET /api/tools?integration=railway was observed spending 19.4s of a 19.5s response re-syncing 13 MCP connections, none of them railway. p99 on /api/tools was 16s over the last day.

  • The pre-read catalog refresh now only considers connections matching the read's integration/owner/connection filter.
  • The stale scan is narrowed per-integration (TTL arm applies only to remote-catalog integrations, config-revision arm only to revised ones) and projects four columns instead of full rows; in steady state it returns zero rows.
  • Remaining refreshes run concurrently (4) across the upstream handshakes, with persists serialized behind a one-permit semaphore — fumadb's sqlite/libSQL transactions share one connection, and concurrent BEGINs silently dropped 4 of 5 rebuilds in a deterministic repro (test included).
  • Refresh failures log a sanitized warning (slug, connection, trigger, error tags) and count on the new executor.tools.list span; the per-connection span is renamed executor.tools.sync_staleexecutor.tools.sync with a trigger attribute.
  • The sandbox tool-search enumeration path passes its namespace down as the read filter.

TTL-expired refresh still happens inline (filter-scoped); moving it off the read path entirely is the follow-up PR, along with claim/backoff schema.

The stale-catalog scan ran unfiltered and refreshed connections sequentially, so a read for one integration paid for every stale connection in the workspace. Scope it to the read filter, narrow the TTL and config-revision triggers to the integrations they can fire for, project only the columns it reads, and refresh concurrently. A plugin defect can no longer fail the read.
Empty-query enumeration filtered tools by exact integration slug after listing everything. Pass it as the read filter instead, so the read refreshes only that integration. Ranked search stays unscoped: its namespace match is token-prefix.
The read refresh fans out to 4 concurrent produceConnectionTools calls,
but fumadb runs a SQLite transaction as raw BEGIN/COMMIT on the shared
connection. The second BEGIN fails with "cannot start a transaction
within a transaction" and the losing persist drops its whole rebuild:
five connections refreshed at once, four rebuilds lost.

Hold a one-permit semaphore around the persist only, so the upstream
resolveTools handshakes keep overlapping. Log refresh failures as a
warning with enumerable fields instead of a debug line carrying the raw
cause, and report a failed count on the tools.list span.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
executor-marketing 1c658ba Commit Preview URL

Branch Preview URL
Aug 16 2026, 01:44 PM

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
executor-cloud 1c658ba Aug 16 2026, 01:44 PM

@github-actions

Copy link
Copy Markdown
Contributor

Cloudflare preview

Console https://executor-preview-pr-1605.executor-e2e.workers.dev
MCP https://executor-preview-pr-1605.executor-e2e.workers.dev/mcp
Deployed commit 1c658ba

Sign-in is Cloudflare Access (one-time PIN to an allowed email). The preview has its own database and encryption key; it is destroyed when this PR closes.

@pkg-pr-new

pkg-pr-new Bot commented Aug 16, 2026

Copy link
Copy Markdown

Open in StackBlitz

@executor-js/cli

npm i https://pkg.pr.new/@executor-js/cli@1605

@executor-js/config

npm i https://pkg.pr.new/@executor-js/config@1605

@executor-js/execution

npm i https://pkg.pr.new/@executor-js/execution@1605

@executor-js/sdk

npm i https://pkg.pr.new/@executor-js/sdk@1605

@executor-js/codemode-core

npm i https://pkg.pr.new/@executor-js/codemode-core@1605

@executor-js/runtime-quickjs

npm i https://pkg.pr.new/@executor-js/runtime-quickjs@1605

@executor-js/plugin-file-secrets

npm i https://pkg.pr.new/@executor-js/plugin-file-secrets@1605

@executor-js/plugin-graphql

npm i https://pkg.pr.new/@executor-js/plugin-graphql@1605

@executor-js/plugin-keychain

npm i https://pkg.pr.new/@executor-js/plugin-keychain@1605

@executor-js/plugin-mcp

npm i https://pkg.pr.new/@executor-js/plugin-mcp@1605

@executor-js/plugin-onepassword

npm i https://pkg.pr.new/@executor-js/plugin-onepassword@1605

@executor-js/plugin-openapi

npm i https://pkg.pr.new/@executor-js/plugin-openapi@1605

executor

npm i https://pkg.pr.new/executor@1605

commit: 1c658ba

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