fix(openapi): query worker thread for REST OpenAPI spec on main thread - #652
Merged
Conversation
When the operations API runs on the main thread (post PR #355), resources are only registered on worker threads, so /api/openapi/rest returned an empty spec. This adds a cross-thread ITC mechanism: the main thread broadcasts RESOURCE_OPENAPI_REQUEST; the first worker with registered resources generates the spec via generateJsonApi and sends it back via RESOURCE_OPENAPI_RESPONSE. Falls back to local resources when running in single-thread mode (resources.size > 0). Resolves #299 (partial — addresses the OpenAPI endpoint concern) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
dawsontoth
approved these changes
May 20, 2026
…OpenAPI requests Without this change, a worker with 0 registered resources would silently drop the ITC request, causing the main thread to wait 5 seconds before timing out. Now every worker responds (even with an empty spec), matching Dawson's review request. Also adds a full test suite for resourceOpenApiRequestHandler including happy-path send/drop assertions and a 'no hang on empty resources' case. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
|
Reviewed; no blockers found. |
…ly reply Without the guard a job-type worker (resources.size === 0) responds to RESOURCE_OPENAPI_REQUEST before an app worker, silently returning an empty spec — identical to the original bug (#299). Restores the early-return guard so only a worker that actually owns resources replies. When no worker has resources the caller receives a 503 after the timeout, which is more honest than an empty spec. Also fixes the unit tests to properly exercise the guard and the happy-path: - 'does not respond when this thread has no registered resources' verifies the guard - Send/drop tests populate the resources map with a minimal skippable entry (isError: true) so Resources.set() wraps it correctly for generateJsonApi Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
RESOURCE_OPENAPI_REQUEST/RESOURCE_OPENAPI_RESPONSE) following the existingCOMPONENT_STATUS_REQUESTpatternserverHandlers.jsgenerates the OpenAPI spec from its local resources and returns it directly to the requesting thread; skips if resources are empty (guards against job-type workers responding before app workers)restOpenAPIHandlerinoperationsServer.tsfalls back to cross-thread query whenresources.size === 0(i.e. running on main thread with worker threads); uses local resources directly in single-thread modePurpose
Resolves the concern from #299 introduced by moving the operations API to the main thread (PR #355): application resources are only registered on worker threads, so
/api/openapi/restwas returning an empty spec when called on the main thread.What to review
server/operationsServer.ts:queryWorkerForOpenApi/attachOpenApiResponseListener— the main-thread side of the query. TherequestIdcounter and pending-request map follow the same pattern asCrossThreadStatusCollectorincomponents/status/crossThread.ts.server/itc/serverHandlers.js:resourceOpenApiRequestHandler— runs on worker threads; guards withresources.size === 0so workers with no registered resources (e.g. job workers at startup) don't respond.Test plan
unitTests/server/itc/serverHandlers.test.jscovering validation, happy-path response, and unreachable-originator drop — all passingGET /api/openapi/restas a super_user, confirm non-empty spec is returnedGenerated by Claude Sonnet 4.6 (agent)