Skip to content
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

[core] call onResponse in as*Stream methods #28111

Merged
merged 8 commits into from Jan 2, 2024

Conversation

deyaaeldeen
Copy link
Member

Packages impacted by this PR

@azure-rest/core-client and @azure/openai

Issues associated with this PR

#28093

Describe the problem that is addressed by this PR

The onResponse callback option is not called in streamCompletions and streamChatCompletions. This is because the asNodeStream and asBrowserStream methods in the internal client don't call them.

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?

This PR addresses the issue by simply calling the onResponse call back in the asNodeStream and asBrowserStream methods. I don't think we want to not call onResponse there.

Are there test cases added in this PR? (If not, why?)

Yes

Provide a list of related PRs (if any)

N/A

Command used to generate this PR:**(Applicable only to SDK release request PRs)

Checklists

  • Added impacted package name to the issue description
  • Does this PR needs any fixes in the SDK Generator?** (If so, create an Issue in the Autorest/typescript repository and link it here)
  • Added a changelog (if necessary)

@azure-sdk
Copy link
Collaborator

azure-sdk commented Dec 27, 2023

API change check

APIView has identified API level changes in this PR and created following API reviews.

@azure/core-sse

Copy link
Member

@xirzec xirzec left a comment

Choose a reason for hiding this comment

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

A few minor remarks, but thanks for digging into this!

sdk/core/core-client-rest/src/sendRequest.ts Outdated Show resolved Hide resolved
@@ -72,7 +74,11 @@ export function ensureAsyncIterable(stream: NodeJS.ReadableStream | ReadableStre
return {
cancel: async () => {
// drain the stream
stream.resume();
if (typeof (stream as Readable).destroy === "function"){
(stream as Readable).destroy();
Copy link
Member

Choose a reason for hiding this comment

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

For the node case I remember calling destroy on the IncomingMessage from http would actually destroy the entire socket and force you to renegotiate TLS in the case that you wanted to make another server request. This was the performance killer for HEAD requests before we fixed it.

Not sure why it would be causing things to hang in this case though. Maybe it's fine to destroy here since we are canceling? Hmm

Copy link
Member Author

Choose a reason for hiding this comment

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

I assume you're referring to the fix in #24356. I looked into this further and here are a few interesting findings:

  • pooled sockets are unrefed but for some reason they still hold up the app
  • message.socket.end() seems like a more graceful way to implement cancellation here as it sends a FIN packet to the server to make it aware that it doesn't have to bother sending more data. I think we still lose the socket eventually which is not great. The other option is to let the data flow from the server and ignore it but that could have an impact on billing/perf. I am happy to revisit this again if a better design emerges.

Addressed in 08b822d.

@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import { Readable } from "stream";
Copy link
Member

Choose a reason for hiding this comment

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

style nit: I'd personally just make a type guard function to check for a "destroy" function and call it rather than pull in node typings just for a cast

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point. I don't like casting here so I changed the input type to be http.IncomingMessage to be honest with the client code, although core-rest-pipeline doesn't actually use it as the public type.

@@ -6,11 +6,13 @@

/// <reference types="node" />

import { IncomingMessage } from 'http';
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
import { IncomingMessage } from 'http';
import type { IncomingMessage } from 'http';

nit

@deyaaeldeen deyaaeldeen merged commit a6c801a into main Jan 2, 2024
23 checks passed
@deyaaeldeen deyaaeldeen deleted the core/fix-onresponse-in-stream branch January 2, 2024 17:33
timovv added a commit to timovv/azure-sdk-for-js that referenced this pull request Feb 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants