Skip to content

fix(client): coalesce catalog refetches after event bursts - #47927

Open
Hona wants to merge 1 commit into
anomalyco:v2from
Hona:catalog-refresh-settle
Open

fix(client): coalesce catalog refetches after event bursts#47927
Hona wants to merge 1 commit into
anomalyco:v2from
Hona:catalog-refresh-settle

Conversation

@Hona

@Hona Hona commented Sep 8, 2026

Copy link
Copy Markdown
Member

A 33-minute Desktop netlog showed GET /api/model fetched 16 times (~270 KB each, 4.3 MB decoded) and GET /api/provider 16 times. One Location's model and provider catalogs were fetched three times within ~190 ms because catalog.updated, integration.updated, and credential.updated each answered with an immediate refetch. /api/command (24), /api/mcp/resource (22), /api/agent, /api/skill, and /api/reference saw the same burst pattern.

sequenceDiagram
  participant S as Server
  participant D as createData
  participant A as /api/model
  S->>D: catalog.updated
  S->>D: integration.updated
  S->>D: credential.updated
  Note over D: invalidate now, one settle timer per resource + Location
  D-->>D: 150 ms quiet
  D->>A: GET /api/model (once)
Loading

Changes — packages/client/src/solid/data.ts

  • Every per-Location catalog event now goes through settle(key, load) instead of refresh(load): catalog.updated, integration.updated, credential.updated, credential.switched, agent.updated, command.updated, skill.updated, reference.updated, config.updated, websearch.updated, and mcp.resources.changed.
  • Settle keys mirror the sync keys, location.<field>:<locationKey>, so different events that ask for the same catalog share one timer. catalog.updated and integration.updated for the same Location now coalesce into one model fetch and one provider fetch.
  • invalidate(...) still runs immediately, so an explicit sync() during the window reads fresh data and already-published data stays visible until the reload lands. Session, permission, form, shell, and VCS handling is unchanged.
case "integration.updated":
  result.location.integration.invalidate(location)
  result.location.model.invalidate(location)
  result.location.provider.invalidate(location)
  settle(`location.integration:${locationKey(location)}`, () => result.location.integration.sync(location))
  settle(`location.model:${locationKey(location)}`, () => result.location.model.sync(location))
  settle(`location.provider:${locationKey(location)}`, () => result.location.provider.sync(location))
  break
Scenario Before After
catalog.updated + integration.updated + credential.updated for one Location in ~190 ms 3 × GET /api/model, 3 × GET /api/provider 1 × GET /api/model, 1 × GET /api/provider
33-minute Desktop session 16 × GET /api/model (4.3 MB decoded), 16 × GET /api/provider 1 fetch per burst per Location
/api/command, /api/mcp/resource, /api/agent, /api/skill, /api/reference one fetch per event (24 and 22 for the first two) one fetch per burst per Location

Follows #47561, which introduced settle for mcp.status.changed.

Copilot AI lite review requested due to automatic review settings September 8, 2026 09:07

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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