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

Update ContextReference & DefaultFromBodyConversionFeature to remove invocation cancellation token usage #2894

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

### Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore <version>

- <entry>
- Update `ContextReference` to no longer use a given invocation's cancellation token (#2894)

### Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore.Analyzers <version>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,14 @@

namespace Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore
{
internal class ContextReference : IDisposable
internal class ContextReference
{
private readonly TaskCompletionSource<bool> _functionStartTask = new();
private readonly TaskCompletionSource<bool> _functionCompletionTask = new();

private TaskCompletionSource<HttpContext> _httpContextValueSource = new();
private TaskCompletionSource<FunctionContext> _functionContextValueSource = new();

private CancellationToken _token;
private CancellationTokenRegistration _tokenRegistration;

public ContextReference(string invocationId)
{
InvocationId = invocationId;
Expand All @@ -32,18 +29,6 @@ public ContextReference(string invocationId)

public TaskCompletionSource<FunctionContext> FunctionContextValueSource { get => _functionContextValueSource; set => _functionContextValueSource = value; }

internal void SetCancellationToken(CancellationToken token)
{
_token = token;
_tokenRegistration = _token.Register(() =>
{
_functionStartTask.TrySetCanceled();
_functionCompletionTask.TrySetCanceled();
_functionContextValueSource.TrySetCanceled();
_httpContextValueSource.TrySetCanceled();
});
}

internal Task InvokeFunctionAsync()
{
_functionStartTask.SetResult(true);
Expand All @@ -59,27 +44,12 @@ internal void CompleteFunction()

if (_httpContextValueSource.Task.IsCompleted)
{
if (_httpContextValueSource.Task.IsCanceled || _token.IsCancellationRequested)
{
_functionCompletionTask.TrySetCanceled();
}
else
{
_functionCompletionTask.TrySetResult(true);
}
_functionCompletionTask.TrySetResult(true);
}
else
{
// we should never reach here b/c the class that calls this needs httpContextValueSource to complete to reach this method
}
}

public void Dispose()
{
if (_tokenRegistration != default)
{
_tokenRegistration.Dispose();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
Expand Down Expand Up @@ -44,7 +44,6 @@ public async Task<FunctionContext> SetHttpContextAsync(string invocationId, Http
public async Task<HttpContext> SetFunctionContextAsync(string invocationId, FunctionContext context)
{
var contextRef = _contextReferenceList.GetOrAdd(invocationId, static id => new ContextReference(id));
contextRef.SetCancellationToken(context.CancellationToken);
contextRef.FunctionContextValueSource.SetResult(context);

_logger.FunctionContextSet(invocationId);
Expand Down Expand Up @@ -85,7 +84,6 @@ public void CompleteFunctionInvocation(string invocationId)
if (_contextReferenceList.TryRemove(invocationId, out var contextRef))
{
contextRef.CompleteFunction();
contextRef.Dispose();
}
else
{
Expand Down
1 change: 1 addition & 0 deletions extensions/Worker.Extensions.Http/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
### Microsoft.Azure.Functions.Worker.Extensions.Http <version>

- The 'FromBody' converter now utilizes `DeserializeAsync` for deserializing JSON content from the request body, enhancing support for asynchronous deserialization. (#2901)
- Update `DefaultFromBodyConversionFeature` to no longer use a given invocation's cancellation token (#2894)
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ internal class DefaultFromBodyConversionFeature : IFromBodyConversionFeature
_ when HasJsonContentType(requestData) =>
await (requestData.FunctionContext.InstanceServices.GetService<IOptions<WorkerOptions>>()?.Value?.Serializer
?? throw new InvalidOperationException("A serializer is not configured for the worker."))
.DeserializeAsync(requestData.Body, targetType, context.CancellationToken),
.DeserializeAsync(requestData.Body, targetType, CancellationToken.None),
_ => throw new InvalidOperationException($"The type '{targetType}' is not supported by the '{nameof(DefaultFromBodyConversionFeature)}'.")
};

Expand Down
Loading