Skip to content

Editorial: use a dedicated parallel queue for the Clients API - #1842

Draft
monica-ch wants to merge 1 commit into
w3c:mainfrom
monica-ch:clients-api-parallel-queue
Draft

Editorial: use a dedicated parallel queue for the Clients API#1842
monica-ch wants to merge 1 commit into
w3c:mainfrom
monica-ch:clients-api-parallel-queue

Conversation

@monica-ch

@monica-ch monica-ch commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Closes #1840. Follow-up to #1755.

Give each {{Clients}} object a dedicated parallel queue and route the operations on {{Clients}} through it, so operations on the same {{Clients}} object do not race with each other (e.g. matchAll iterating over service worker clients while claim is mutating their [=active service worker=]).

Changes

  • Add a <dfn export for="Clients">Clients parallel queue</dfn> (a [=parallel queue=]) attached to each {{Clients}} object, following the same pattern as the name to cache map parallel queue introduced in Editorial: serialize CacheStorage access on a dedicated parallel queue #1838.
  • Route the following method algorithms through it, replacing their existing top-level Run … in parallel block:
    • {{Clients/get(id)}}
    • {{Clients/matchAll(options)}}
    • {{Clients/openWindow(url)}}
    • {{Clients/claim()}}
  • Wrap the two remaining bare Resolve |promise| with undefined. steps (in get() and claim()) in Queue a task on |promise|'s [=responsible event loop=] using the [=DOM manipulation task source=], matching the pattern already used in matchAll() and consistent with the queue-a-task refactor from Editorial: Queue a task to resolve/reject promise or when fire an event. #1755.

Total change: +10 / −6 in index.bs, one commit.

Rationale

Yoshi flagged this concern during #1755 review:

I just wondered what happens if one of the service worker clients has been removed or gets execution ready flag during the sub step execution, and suggest to run Clients API algorithm within the dedicated parallel queue to prevent unexpected modifications to clients.

#1836 landed the queue-a-task-for-resolve fixes for these methods. This PR delivers the sibling parallel-queue work that was explicitly deferred in the split plan.

Out of scope

  • {{Client/postMessage(message, options)}} — lives on {{Client}}, not {{Clients}}, and does a single-client lookup rather than iterating the full client list. Can be a further follow-up if needed.
  • {{WindowClient/focus()}} and {{WindowClient/navigate(url)}} — already skip the in parallel block entirely and use Queue a task on the client's own event loop, so no parallel-queue treatment is meaningful for them.

Related


Preview | Diff

Give each Clients object a dedicated parallel queue and route Clients.get, Clients.matchAll, Clients.openWindow, and Clients.claim through it, so operations on the same Clients object do not race with each other. Wrap the remaining bare Resolve steps in get() and claim() in Queue a task on the promise's responsible event loop, matching the pattern used in the other queue-a-task refactors.

Closes: w3c#1840
@monica-ch
monica-ch force-pushed the clients-api-parallel-queue branch from 7f622b8 to 805ee59 Compare August 4, 2026 22:25
Comment thread index.bs
Comment on lines +1388 to +1389
Each {{Clients}} object has an associated <dfn>Clients parallel queue</dfn> (a [=parallel queue=]) used to serialize the {{Clients}} object's operations.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Recognizing this patch is a WIP, I think this is currently under-constrained and it probably makes sense to do this like you've done it for the Cache API in #1838 which is basically one-per-storage-key. (Whereas this currently seems to be 1-per-ServiceWorker instance.)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Agreed, 1-per-Clients is under-constrained. Will rework to 1-per-storage-key matching #1838.

Quick clarification before I push: #1838 hangs the queue off [=name to cache map=] because that map is itself per-storage-key. Clients don't have an equivalent map — the [=/service worker clients=] list is UA-wide, filtered by storage key. Would you prefer a UA-level <dfn>Clients parallel queue</dfn> map keyed by storage key, or a prose "for each storage key, the UA has an associated Clients parallel queue" form?

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.

Use a dedicated parallel queue for the Clients API

2 participants