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

Handle cancellation token if function is invoked before cancellation token #2546

Merged
merged 5 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ public async ValueTask<FunctionInputBindingResult> BindFunctionInputAsync(Functi
{
ObjectDisposedThrowHelper.ThrowIf(_disposed, this);

await _semaphoreSlim.WaitAsync(WaitTimeInMilliSeconds, context.CancellationToken);
// Setting second parameter to CancellationToken.None to prevent a TaskCancelledException if the
// pipeline cancels the code before the function is invoked. This way the customer code will be invoked
// and they can handle the cancellation token.
await _semaphoreSlim.WaitAsync(WaitTimeInMilliSeconds, CancellationToken.None);
aishwaryabh marked this conversation as resolved.
Show resolved Hide resolved

try
{
Expand Down
41 changes: 41 additions & 0 deletions test/DotNetWorkerTests/DefaultModelBindingFeatureTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,47 @@ public async void BindFunctionInputAsync_Populates_ParametersUsingConverters()
Assert.Equal("0ab4800e-1308-4e9f-be5f-4372717e68eb", guid.ToString());
}

[Fact]
public async void BindFunctionInputAsync_IgnoreCancellationToken()
aishwaryabh marked this conversation as resolved.
Show resolved Hide resolved
{
// Arrange
var parameters = new List<FunctionParameter>()
{
new("myQueueItem",typeof(Book)),
new ("myGuid", typeof(Guid))
};
IInvocationFeatures features = new InvocationFeatures(Enumerable.Empty<IInvocationFeatureProvider>());
features.Set(_serviceProvider.GetService<IInputConversionFeature>());
features.Set<IFunctionBindingsFeature>(new TestFunctionBindingsFeature()
{
InputData = new Dictionary<string, object>
{
{ "myQueueItem","{\"id\":\"foo\", \"title\":\"bar\"}" },
{ "myGuid","0ab4800e-1308-4e9f-be5f-4372717e68eb" }
}
});

var definition = new TestFunctionDefinition(parameters: parameters, inputBindings: new Dictionary<string, BindingMetadata>
{
{ "myQueueItem", new TestBindingMetadata("myQueueItem","queueTrigger",BindingDirection.In) },
{ "myGuid", new TestBindingMetadata("myGuid","queueTrigger",BindingDirection.In) }
});

// Register a cancellation token
var cts = new CancellationTokenSource();
cts.Cancel();
var functionContext = new TestFunctionContext(definition, invocation: null, cts.Token, serviceProvider: _serviceProvider, features: features);

// Act
var bindingResult = await _functionInputBindingFeature.BindFunctionInputAsync(functionContext);
var parameterValuesArray = bindingResult.Values;
// Assert
var book = TestUtility.AssertIsTypeAndConvert<Book>(parameterValuesArray[0]);
Assert.Equal("foo", book.Id);
var guid = TestUtility.AssertIsTypeAndConvert<Guid>(parameterValuesArray[1]);
Assert.Equal("0ab4800e-1308-4e9f-be5f-4372717e68eb", guid.ToString());
}

[Fact]
public async void BindFunctionInputAsync_Populates_Parameter_Using_DefaultValue_When_CouldNot_Populate_From_InputData()
{
Expand Down
Loading