-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Add invoke support for web pubsub client #36750
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
API Change CheckAPIView identified API level changes in this PR and created the following API reviews |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds invoke support to the @azure/web-pubsub-client package, enabling clients to send upstream events and await correlated responses from the service. This implements a request-response pattern on top of the existing WebSocket-based pub/sub messaging system.
Key Changes
- New InvocationManager: Manages pending invocations with correlation by invocation ID, supporting abort signals and automatic cleanup on disconnection
- New message types: Adds
InvokeMessage,InvokeResponseMessage, andCancelInvocationMessageto the protocol - Public API: Introduces
invokeEvent()method for sending invocations with configurable invocation IDs and abort signals - Error handling: New
InvocationErrorclass for invocation-specific failures, which bypasses retry logic to prevent duplicate processing
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
src/invocationManager.ts |
New manager class for tracking pending invocations, handling promise resolution/rejection, and managing abort signal lifecycle |
src/webPubSubClient.ts |
Integrates InvocationManager; adds invokeEvent() public API; handles invokeResponse messages; rejects pending invocations on disconnection; prevents retry on InvocationError |
src/protocols/jsonProtocolBase.ts |
Adds parsing and serialization for invoke, invokeResponse, and cancelInvocation messages |
src/models/messages.ts |
Defines InvokeMessage, InvokeResponseMessage, CancelInvocationMessage, and InvokeResponseError interfaces |
src/models/index.ts |
Exports InvokeEventOptions and InvokeEventResult for public API surface |
src/errors/index.ts |
Adds InvocationError class and InvocationErrorOptions interface |
test/invocationManager.spec.ts |
Comprehensive unit tests for InvocationManager covering registration, resolution, rejection, abort handling, and rejectAll |
test/client.invoke.spec.ts |
Integration tests for invokeEvent covering successful invocations, service errors, and abort signal handling with cancelInvocation |
review/web-pubsub-client-node.api.md |
API review file updated with new public interfaces and types |
README.md |
Documentation example showing how to use the new invokeEvent feature |
| export interface CancelInvocationMessage extends WebPubSubMessageBase { | ||
| readonly kind: "cancelInvocation"; |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add JSDoc comments to the kind and invocationId properties of CancelInvocationMessage to match the documentation pattern used in other message interfaces.
| export interface CancelInvocationMessage extends WebPubSubMessageBase { | |
| readonly kind: "cancelInvocation"; | |
| export interface CancelInvocationMessage extends WebPubSubMessageBase { | |
| /** | |
| * The message kind. | |
| */ | |
| readonly kind: "cancelInvocation"; | |
| /** | |
| * The invocation ID to cancel. | |
| */ |
| } | ||
| } | ||
|
|
||
|
|
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Remove the extra blank line to maintain consistent code formatting.
| await expect(invokePromise).rejects.toThrow(InvocationError); | ||
|
|
||
| // Verify cancelInvocation message is sent | ||
| // The last call should be cancelInvocation. |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Remove the trailing space at the end of the comment line.
| // The last call should be cancelInvocation. | |
| // The last call should be cancelInvocation. |
| export interface InvocationErrorOptions { | ||
| invocationId: string; |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add JSDoc comments to the InvocationErrorOptions interface properties to be consistent with the pattern used for SendMessageErrorOptions above it.
| export interface InvocationErrorOptions { | |
| invocationId: string; | |
| export interface InvocationErrorOptions { | |
| /** | |
| * The invocation id of the request. | |
| */ | |
| invocationId: string; | |
| /** | |
| * Error details from the service if available. | |
| */ |
| export interface InvokeMessage extends WebPubSubMessageBase { | ||
| readonly kind: "invoke"; |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add JSDoc comments to the kind and invocationId properties of InvokeMessage to match the documentation pattern used in other message interfaces like SendToGroupMessage.
| export interface InvokeMessage extends WebPubSubMessageBase { | |
| readonly kind: "invoke"; | |
| export interface InvokeMessage extends WebPubSubMessageBase { | |
| /** | |
| * Message type | |
| */ | |
| readonly kind: "invoke"; | |
| /** | |
| * The invocation id | |
| */ |
| */ | ||
| export interface InvokeMessage extends WebPubSubMessageBase { | ||
| readonly kind: "invoke"; | ||
| invocationId: string; |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add JSDoc comments to the target property of InvokeMessage to match the documentation pattern used in other message interfaces.
| invocationId: string; | |
| invocationId: string; | |
| /** | |
| * The invocation target type. Currently, only upstream events are supported. | |
| */ |
| export interface InvokeResponseMessage extends WebPubSubMessageBase { | ||
| readonly kind: "invokeResponse"; | ||
| invocationId: string; | ||
| success?: boolean; | ||
| dataType?: WebPubSubDataType; | ||
| data?: JSONTypes | ArrayBuffer; |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add JSDoc comments to all properties of InvokeResponseMessage to match the documentation pattern used in other message interfaces like SendToGroupMessage.
| export interface InvokeResponseMessage extends WebPubSubMessageBase { | |
| readonly kind: "invokeResponse"; | |
| invocationId: string; | |
| success?: boolean; | |
| dataType?: WebPubSubDataType; | |
| data?: JSONTypes | ArrayBuffer; | |
| export interface InvokeResponseMessage extends WebPubSubMessageBase { | |
| /** | |
| * Message type. | |
| */ | |
| readonly kind: "invokeResponse"; | |
| /** | |
| * The invocation ID that this response is for. | |
| */ | |
| invocationId: string; | |
| /** | |
| * Indicates whether the invocation was successful. | |
| */ | |
| success?: boolean; | |
| /** | |
| * Data type of the payload. | |
| */ | |
| dataType?: WebPubSubDataType; | |
| /** | |
| * Payload data. | |
| */ | |
| data?: JSONTypes | ArrayBuffer; | |
| /** | |
| * Error details if the invocation failed. | |
| */ |
| export interface InvokeResponseError { | ||
| name: string; |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add JSDoc comments to the name and message properties of InvokeResponseError to match the documentation pattern used in other interfaces.
| export interface InvokeResponseError { | |
| name: string; | |
| export interface InvokeResponseError { | |
| /** | |
| * The error name. | |
| */ | |
| name: string; | |
| /** | |
| * The error message. | |
| */ |
| } | ||
| }; | ||
|
|
||
| abortSignal.addEventListener("abort", onAbort); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these listeners may leak if _sendMessage throws in _invokeEventAttempt?
Packages impacted by this PR
@azure/web-pubsub-client
Issues associated with this PR
Describe the problem that is addressed by this PR
What are the possible designs available to address the problem? If there are more than one possible design, why was the one in this PR chosen?
Are there test cases added in this PR? (If not, why?)
Provide a list of related PRs (if any)
Command used to generate this PR:**(Applicable only to SDK release request PRs)
Checklists