@@ -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}
0 commit comments