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

RequestContext.CancellationToken is never used #34988

Open
heaths opened this issue Mar 17, 2023 · 7 comments
Open

RequestContext.CancellationToken is never used #34988

heaths opened this issue Mar 17, 2023 · 7 comments
Labels
Azure.Core Client This issue points to a problem in the data-plane of the library.
Milestone

Comments

@heaths
Copy link
Member

heaths commented Mar 17, 2023

For APIs that expose a RequestContext instead of a CancellationToken, users can only pass a CancellationToken by setting RequestContext.CancellationToken; however, VS shows 0 references to RequestContext.CancellationToken and walking through the pipeline code, everything seems to read HttpMessage.CancellationToken which is only set by HttpPipeline.Send and SendAsync - not something most users are really meant to call themselves.

Looking at generated client code like

internal virtual async Task<Operation<BinaryData>> StartAnalyzeConversationAsync(WaitUntil waitUntil, RequestContent content, RequestContext context = null)
{
Argument.AssertNotNull(content, nameof(content));
using var scope = ClientDiagnostics.CreateScope("ConversationAnalysisClient.StartAnalyzeConversation");
scope.Start();
try
{
using HttpMessage message = CreateStartAnalyzeConversationRequest(content, context);
return await ProtocolOperationHelpers.ProcessMessageAsync(_pipeline, message, ClientDiagnostics, "ConversationAnalysisClient.StartAnalyzeConversation", OperationFinalStateVia.Location, context, waitUntil).ConfigureAwait(false);
}
catch (Exception e)
{
scope.Failed(e);
throw;
}
}
and its request factory like
internal HttpMessage CreateStartAnalyzeConversationRequest(RequestContent content, RequestContext context)
{
var message = _pipeline.CreateMessage(context, ResponseClassifier200202);
var request = message.Request;
request.Method = RequestMethod.Post;
var uri = new RawRequestUriBuilder();
uri.Reset(_endpoint);
uri.AppendRaw("/language", false);
uri.AppendPath("/analyze-conversations/jobs", false);
uri.AppendQuery("api-version", _apiVersion, true);
request.Uri = uri;
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Content-Type", "application/json");
request.Content = content;
return message;
}
I also see nowhere that RequestContext.CancellationToken is used; thus, it seems impossible for customers to cancel any methods taking a RequestContext.

@heaths heaths added Client This issue points to a problem in the data-plane of the library. Azure.Core labels Mar 17, 2023
@heaths
Copy link
Member Author

heaths commented Mar 17, 2023

I found this while changing GetSecretIfExists using a CancellationToken to a GetSecret overload taking a RequestContext for PR #33767, which is more robust. To work around this, in my custom pipeline (mainly just wrappers) I'm passing context?.CancellationToken ?? default to HttpPipeline.Send and SendAsync but it seems this shouldn't be necessary. Perhaps HttpPipeline.CreateMessage should set HttpMessage.CancellationToken from the optionally passed-in RequestContext.CancellationToken.

@heaths
Copy link
Member Author

heaths commented Mar 17, 2023

@annelo-msft pointed out that the RequestContext.CancellationToken is getting used via an extension method. Indeed, I'm seeing this get called in CLU which calls ProtocolOperationHelpers.ProcessMessage:

return ProtocolOperationHelpers.ProcessMessage(_pipeline, message, ClientDiagnostics, "ConversationAnalysisClient.StartAnalyzeConversation", OperationFinalStateVia.Location, context, waitUntil);

However, if you call HttpPipeline.Send or SendAsync directly, this does not appear to be the case. Still seems it would be more robust to have HttpPipeline.CreateMessage set the CancellationToken as mentioned in my comment above since all code seems to be calling that:

var message = _pipeline.CreateMessage(context, ResponseClassifier200202);

@annelo-msft
Copy link
Member

@heaths, given this finding, is there still an issue in CLU? Or only in KeyVault where the pipeline is being called manually? What libraries are actually affected?

@heaths
Copy link
Member Author

heaths commented Mar 17, 2023

No, it seems there's no issue with CLU. Only when trying to add a convenience method taking a RequestContext, which @KrzysztofCwalina, @tg-msft, and @m-nash approved for this; though there's another potential blocker to #33767 outside this problem.

@annelo-msft
Copy link
Member

annelo-msft commented Mar 17, 2023

Could the extension method be called in the convenience method, or is that not possible?

@heaths
Copy link
Member Author

heaths commented Mar 17, 2023

Sure it could, but now there's an implicit dependency people just have to know to use or behavior may vary (and it's not like many libraries seem to test cancellation). What's wrong with making sure it's always set in a call that everyone has to use anyway like HttpPipeline.CreateMessage?

@annelo-msft
Copy link
Member

Nothing is wrong with it, and I agree it's a nicer approach. I ask primarily to evaluate whether you're blocked or not, as a means of prioritizing this relative to other tasks.

@annelo-msft annelo-msft changed the title RequstContext.CancellationToken is never used RequestContext.CancellationToken is never used Mar 24, 2023
@annelo-msft annelo-msft added this to the Backlog milestone May 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Azure.Core Client This issue points to a problem in the data-plane of the library.
Projects
None yet
Development

No branches or pull requests

2 participants