in src/Microsoft.Azure.WebJobs.Host/Executors/FunctionExecutor.cs [487:551]
internal async Task ExecuteWithWatchersAsync(IFunctionInstanceEx instance,
ParameterHelper parameterHelper,
ILogger logger,
CancellationTokenSource functionCancellationTokenSource)
{
await parameterHelper.PrepareParametersAsync();
SingletonLock singleton = null;
if (parameterHelper.HasSingleton)
{
// if the function is a Singleton, acquire the lock
singleton = await parameterHelper.GetSingletonLockAsync();
await singleton.AcquireAsync(functionCancellationTokenSource.Token);
}
using (CancellationTokenSource timeoutTokenSource = new CancellationTokenSource())
{
var timeoutAttribute = instance.FunctionDescriptor.TimeoutAttribute;
bool throwOnTimeout = timeoutAttribute?.ThrowOnTimeout ?? false;
var timer = StartFunctionTimeout(instance, timeoutAttribute, timeoutTokenSource, logger);
TimeSpan timerInterval = timer == null ? TimeSpan.MinValue : TimeSpan.FromMilliseconds(timer.Interval);
try
{
using (logger.BeginScope(new Dictionary<string, object>
{
[LogConstants.CategoryNameKey] = LogCategories.CreateFunctionCategory(instance.FunctionDescriptor.LogName),
[LogConstants.LogLevelKey] = LogLevel.Information
}))
{
var filters = GetFilters<IFunctionInvocationFilter>(_globalFunctionFilters, instance.FunctionDescriptor, parameterHelper.JobInstance);
var invoker = FunctionInvocationFilterInvoker.Create(parameterHelper.Invoker, filters, instance, parameterHelper, logger);
object returnValue = null;
if (timer == null)
{
returnValue = await invoker.InvokeAsync(parameterHelper.JobInstance, parameterHelper.InvokeParameters);
}
else
{
returnValue = await InvokeWithTimeoutAsync(invoker, parameterHelper, timeoutTokenSource, functionCancellationTokenSource, throwOnTimeout, timerInterval, instance);
}
parameterHelper.SetReturnValue(returnValue);
}
}
finally
{
if (timer != null)
{
timer.Stop();
timer.Dispose();
}
}
}
using (logger.BeginScope(_outputBindingScope))
{
await parameterHelper.ProcessOutputParameters(functionCancellationTokenSource.Token);
}
if (singleton != null)
{
await singleton.ReleaseAsync(functionCancellationTokenSource.Token);
}
}