Skip to content

Commit ab84ce5

Browse files
committed
Refactoring function value loader and invoker
1 parent 593f621 commit ab84ce5

File tree

6 files changed

+191
-151
lines changed

6 files changed

+191
-151
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Diagnostics;
6+
using Microsoft.CodeAnalysis;
7+
8+
namespace Microsoft.Azure.WebJobs.Script.Description
9+
{
10+
[CLSCompliant(false)]
11+
public static class DiagnosticSeverityExtensions
12+
{
13+
public static TraceLevel ToTraceLevel(this DiagnosticSeverity severity)
14+
{
15+
var level = TraceLevel.Off;
16+
switch (severity)
17+
{
18+
case DiagnosticSeverity.Hidden:
19+
level = TraceLevel.Verbose;
20+
break;
21+
case DiagnosticSeverity.Info:
22+
level = TraceLevel.Info;
23+
break;
24+
case DiagnosticSeverity.Warning:
25+
level = TraceLevel.Warning;
26+
break;
27+
case DiagnosticSeverity.Error:
28+
level = TraceLevel.Error;
29+
break;
30+
}
31+
32+
return level;
33+
}
34+
}
35+
}

src/WebJobs.Script/Description/DotNet/DotNetFunctionInvoker.cs

Lines changed: 16 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,15 @@ public sealed class DotNetFunctionInvoker : FunctionInvokerBase
2929
private readonly Collection<FunctionBinding> _inputBindings;
3030
private readonly Collection<FunctionBinding> _outputBindings;
3131
private readonly IFunctionEntryPointResolver _functionEntryPointResolver;
32-
private readonly ReaderWriterLockSlim _functionValueLoaderLock = new ReaderWriterLockSlim();
3332
private readonly ICompilationService _compilationService;
33+
private readonly FunctionLoader<MethodInfo> _functionLoader;
3434
private readonly IMetricsLogger _metricsLogger;
3535

3636
private FunctionSignature _functionSignature;
3737
private IFunctionMetadataResolver _metadataResolver;
3838
private Action _reloadScript;
3939
private Action _restorePackages;
4040
private Action<MethodInfo, object[], object[], object> _resultProcessor;
41-
private FunctionValueLoader _functionValueLoader;
4241
private string[] _watchedFileTypes;
4342

4443
private static readonly string[] AssemblyFileTypes = { ".dll", ".exe" };
@@ -62,7 +61,7 @@ internal DotNetFunctionInvoker(ScriptHost host, FunctionMetadata functionMetadat
6261

6362
_resultProcessor = CreateResultProcessor();
6463

65-
_functionValueLoader = FunctionValueLoader.Create(CreateFunctionTarget);
64+
_functionLoader = new FunctionLoader<MethodInfo>(CreateFunctionTarget);
6665

6766
_reloadScript = ReloadScript;
6867
_reloadScript = _reloadScript.Debounce();
@@ -114,7 +113,7 @@ public override void OnError(Exception ex)
114113
private void ReloadScript()
115114
{
116115
// Reset cached function
117-
ResetFunctionValue();
116+
_functionLoader.Reset();
118117
TraceOnPrimaryHost(string.Format(CultureInfo.InvariantCulture, "Script for function '{0}' changed. Reloading.", Metadata.Name), TraceLevel.Info);
119118

120119
ImmutableArray<Diagnostic> compilationResult = ImmutableArray<Diagnostic>.Empty;
@@ -151,23 +150,7 @@ private void ReloadScript()
151150
}
152151
}
153152

154-
private void ResetFunctionValue()
155-
{
156-
_functionValueLoaderLock.EnterWriteLock();
157-
try
158-
{
159-
if (_functionValueLoader != null)
160-
{
161-
_functionValueLoader.Dispose();
162-
}
163-
164-
_functionValueLoader = FunctionValueLoader.Create(CreateFunctionTarget);
165-
}
166-
finally
167-
{
168-
_functionValueLoaderLock.ExitWriteLock();
169-
}
170-
}
153+
internal Task<MethodInfo> GetFunctionTargetAsync() => _functionLoader.GetFunctionTargetAsync();
171154

172155
private void RestorePackages()
173156
{
@@ -203,7 +186,7 @@ protected override async Task InvokeCore(object[] parameters, FunctionInvocation
203186
{
204187
// Separate system parameters from the actual method parameters
205188
object[] originalParameters = parameters;
206-
MethodInfo function = await GetFunctionTargetAsync();
189+
MethodInfo function = await _functionLoader.GetFunctionTargetAsync();
207190
int actualParameterCount = function.GetParameters().Length;
208191
object[] systemParameters = parameters.Skip(actualParameterCount).ToArray();
209192
parameters = parameters.Take(actualParameterCount).ToArray();
@@ -252,36 +235,6 @@ private object[] ProcessInputParameters(object[] parameters)
252235
return parameters;
253236
}
254237

255-
internal async Task<MethodInfo> GetFunctionTargetAsync(int attemptCount = 0)
256-
{
257-
FunctionValueLoader currentValueLoader;
258-
_functionValueLoaderLock.EnterReadLock();
259-
try
260-
{
261-
currentValueLoader = _functionValueLoader;
262-
}
263-
finally
264-
{
265-
_functionValueLoaderLock.ExitReadLock();
266-
}
267-
268-
try
269-
{
270-
return await currentValueLoader;
271-
}
272-
catch (OperationCanceledException)
273-
{
274-
// If the current task we were awaiting on was cancelled due to a
275-
// cache refresh, retry, which will use the new loader
276-
if (attemptCount > 2)
277-
{
278-
throw;
279-
}
280-
}
281-
282-
return await GetFunctionTargetAsync(++attemptCount);
283-
}
284-
285238
private async Task<MethodInfo> CreateFunctionTarget(CancellationToken cancellationToken)
286239
{
287240
try
@@ -341,8 +294,7 @@ private void TraceCompilationDiagnostics(ImmutableArray<Diagnostic> diagnostics)
341294
{
342295
foreach (var diagnostic in diagnostics.Where(d => !d.IsSuppressed))
343296
{
344-
TraceLevel level = GetTraceLevelFromDiagnostic(diagnostic);
345-
TraceWriter.Trace(diagnostic.ToString(), level, PrimaryHostTraceProperties);
297+
TraceWriter.Trace(diagnostic.ToString(), diagnostic.Severity.ToTraceLevel(), PrimaryHostTraceProperties);
346298

347299
ImmutableArray<Diagnostic> scriptDiagnostics = GetFunctionDiagnostics(diagnostic);
348300

@@ -448,6 +400,16 @@ private static object GetTaskResult(Task task)
448400
return null;
449401
}
450402

403+
protected override void Dispose(bool disposing)
404+
{
405+
base.Dispose(disposing);
406+
407+
if (disposing)
408+
{
409+
_functionLoader.Dispose();
410+
}
411+
}
412+
451413
private Action<MethodInfo, object[], object[], object> CreateResultProcessor()
452414
{
453415
var bindings = _inputBindings.Union(_outputBindings).OfType<IResultProcessingBinding>();
@@ -472,27 +434,5 @@ private Action<MethodInfo, object[], object[], object> CreateResultProcessor()
472434

473435
return processor ?? ((_, __, ___, ____) => { /*noop*/ });
474436
}
475-
476-
private static TraceLevel GetTraceLevelFromDiagnostic(Diagnostic diagnostic)
477-
{
478-
var level = TraceLevel.Off;
479-
switch (diagnostic.Severity)
480-
{
481-
case DiagnosticSeverity.Hidden:
482-
level = TraceLevel.Verbose;
483-
break;
484-
case DiagnosticSeverity.Info:
485-
level = TraceLevel.Info;
486-
break;
487-
case DiagnosticSeverity.Warning:
488-
level = TraceLevel.Warning;
489-
break;
490-
case DiagnosticSeverity.Error:
491-
level = TraceLevel.Error;
492-
break;
493-
}
494-
495-
return level;
496-
}
497437
}
498438
}

src/WebJobs.Script/Description/DotNet/FunctionValueLoader.cs

Lines changed: 0 additions & 74 deletions
This file was deleted.

0 commit comments

Comments
 (0)