7
7
using System . Collections . Immutable ;
8
8
using System . IO ;
9
9
using System . Linq ;
10
- using System . Threading ;
11
10
using System . Threading . Tasks ;
12
11
using Microsoft . Azure . WebJobs . Logging ;
13
- using Microsoft . Azure . WebJobs . Script . Configuration ;
14
12
using Microsoft . Azure . WebJobs . Script . Description ;
15
13
using Microsoft . Azure . WebJobs . Script . Diagnostics . Extensions ;
16
- using Microsoft . Azure . WebJobs . Script . Workers ;
17
14
using Microsoft . Azure . WebJobs . Script . Workers . Http ;
18
15
using Microsoft . Azure . WebJobs . Script . Workers . Rpc ;
19
- using Microsoft . Extensions . Configuration ;
20
16
using Microsoft . Extensions . DependencyInjection ;
21
17
using Microsoft . Extensions . Logging ;
22
18
using Microsoft . Extensions . Options ;
23
19
24
20
namespace Microsoft . Azure . WebJobs . Script
25
21
{
26
- public class FunctionMetadataManager : IFunctionMetadataManager
22
+ public sealed class FunctionMetadataManager : IFunctionMetadataManager , IDisposable
27
23
{
28
24
private const string FunctionConfigurationErrorMessage = "Unable to determine the primary function script. Make sure at least one script file is present. Try renaming your entry point script to 'run' or alternatively you can specify the name of the entry point script explicitly by adding a 'scriptFile' property to your function metadata." ;
29
25
private const string MetadataProviderName = "Custom" ;
30
26
private readonly IServiceProvider _serviceProvider ;
31
- private IFunctionMetadataProvider _functionMetadataProvider ;
27
+ private readonly IFunctionMetadataProvider _functionMetadataProvider ;
28
+ private readonly IEnvironment _environment ;
29
+
30
+ private readonly IOptionsMonitor < LanguageWorkerOptions > _languageOptions ;
31
+ private IDisposable _onChangeSubscription ;
32
+ private IOptions < ScriptJobHostOptions > _scriptOptions ;
33
+ private ILogger _logger ;
32
34
private bool _isHttpWorker ;
33
- private IEnvironment _environment ;
34
35
private bool _servicesReset = false ;
35
- private ILogger _logger ;
36
- private IOptions < ScriptJobHostOptions > _scriptOptions ;
37
36
private ImmutableArray < FunctionMetadata > _functionMetadataArray ;
38
37
private Dictionary < string , ICollection < string > > _functionErrors = new Dictionary < string , ICollection < string > > ( ) ;
39
38
private ConcurrentDictionary < string , FunctionMetadata > _functionMetadataMap = new ConcurrentDictionary < string , FunctionMetadata > ( StringComparer . OrdinalIgnoreCase ) ;
40
39
41
- public FunctionMetadataManager ( IOptions < ScriptJobHostOptions > scriptOptions , IFunctionMetadataProvider functionMetadataProvider ,
42
- IOptions < HttpWorkerOptions > httpWorkerOptions , IScriptHostManager scriptHostManager , ILoggerFactory loggerFactory ,
43
- IEnvironment environment )
40
+ public FunctionMetadataManager (
41
+ IOptions < ScriptJobHostOptions > scriptOptions ,
42
+ IFunctionMetadataProvider functionMetadataProvider ,
43
+ IOptions < HttpWorkerOptions > httpWorkerOptions ,
44
+ IScriptHostManager scriptHostManager ,
45
+ ILoggerFactory loggerFactory ,
46
+ IEnvironment environment ,
47
+ IOptionsMonitor < LanguageWorkerOptions > languageOptions )
44
48
{
45
49
_scriptOptions = scriptOptions ;
46
50
_serviceProvider = scriptHostManager as IServiceProvider ;
@@ -49,6 +53,9 @@ public FunctionMetadataManager(IOptions<ScriptJobHostOptions> scriptOptions, IFu
49
53
_isHttpWorker = httpWorkerOptions ? . Value ? . Description != null ;
50
54
_environment = environment ;
51
55
56
+ _languageOptions = languageOptions ;
57
+ _onChangeSubscription = languageOptions . OnChange ( _ => _servicesReset = true ) ;
58
+
52
59
// Every time script host is re-initializing, we also need to re-initialize
53
60
// services that change with the scope of the script host.
54
61
scriptHostManager . ActiveHostChanged += ( s , e ) =>
@@ -60,8 +67,10 @@ public FunctionMetadataManager(IOptions<ScriptJobHostOptions> scriptOptions, IFu
60
67
} ;
61
68
}
62
69
70
+ /// <inheritdoc />
63
71
public ImmutableDictionary < string , ImmutableArray < string > > Errors { get ; private set ; }
64
72
73
+ /// <inheritdoc />
65
74
public bool TryGetFunctionMetadata ( string functionName , out FunctionMetadata functionMetadata , bool forceRefresh )
66
75
{
67
76
if ( forceRefresh )
@@ -85,18 +94,21 @@ public bool TryGetFunctionMetadata(string functionName, out FunctionMetadata fun
85
94
/// <param name="applyAllowList">Apply functions allow list filter.</param>
86
95
/// <param name="includeCustomProviders">Include any metadata provided by IFunctionProvider when loading the metadata.</param>
87
96
/// <returns> An Immutable array of FunctionMetadata.</returns>
88
- public ImmutableArray < FunctionMetadata > GetFunctionMetadata ( bool forceRefresh , bool applyAllowList = true , bool includeCustomProviders = true , IList < RpcWorkerConfig > workerConfigs = null )
97
+ public ImmutableArray < FunctionMetadata > GetFunctionMetadata ( bool forceRefresh , bool applyAllowList = true , bool includeCustomProviders = true )
89
98
{
90
99
if ( forceRefresh || _servicesReset || _functionMetadataArray . IsDefaultOrEmpty )
91
100
{
92
- _functionMetadataArray = LoadFunctionMetadata ( forceRefresh , includeCustomProviders , workerConfigs : workerConfigs ) ;
101
+ _functionMetadataArray = LoadFunctionMetadata ( forceRefresh , includeCustomProviders ) ;
93
102
_logger . FunctionMetadataManagerFunctionsLoaded ( ApplyAllowList ( _functionMetadataArray ) . Count ( ) ) ;
94
103
_servicesReset = false ;
95
104
}
96
105
97
106
return applyAllowList ? ApplyAllowList ( _functionMetadataArray ) : _functionMetadataArray ;
98
107
}
99
108
109
+ /// <inheritdoc />
110
+ public void Dispose ( ) => _onChangeSubscription . Dispose ( ) ;
111
+
100
112
private ImmutableArray < FunctionMetadata > ApplyAllowList ( ImmutableArray < FunctionMetadata > metadataList )
101
113
{
102
114
var allowList = _scriptOptions . Value ? . Functions ;
@@ -119,25 +131,16 @@ private void InitializeServices()
119
131
// Resetting the logger switches the logger scope to Script Host level,
120
132
// also making the logs available to Application Insights
121
133
_logger = _serviceProvider ? . GetService < ILoggerFactory > ( ) . CreateLogger ( LogCategories . Startup ) ;
122
- _servicesReset = true ;
123
- }
124
134
125
- /// <summary>
126
- /// This is the worker configuration created in the jobhost scope during placeholder initialization
127
- /// This is used as a fallback incase the config is not passed down from previous method call.
128
- /// </summary>
129
- private IList < RpcWorkerConfig > GetFallbackWorkerConfig ( )
130
- {
131
- return _serviceProvider . GetService < IOptionsMonitor < LanguageWorkerOptions > > ( ) . CurrentValue . WorkerConfigs ;
135
+ _servicesReset = true ;
132
136
}
133
137
134
138
/// <summary>
135
139
/// Read all functions and populate function metadata.
136
140
/// </summary>
137
- internal ImmutableArray < FunctionMetadata > LoadFunctionMetadata ( bool forceRefresh = false , bool includeCustomProviders = true , IFunctionInvocationDispatcher dispatcher = null , IList < RpcWorkerConfig > workerConfigs = null )
141
+ internal ImmutableArray < FunctionMetadata > LoadFunctionMetadata ( bool forceRefresh = false , bool includeCustomProviders = true )
138
142
{
139
- workerConfigs ??= GetFallbackWorkerConfig ( ) ;
140
-
143
+ var workerConfigs = _languageOptions . CurrentValue . WorkerConfigs ;
141
144
_functionMetadataMap . Clear ( ) ;
142
145
143
146
ICollection < string > functionsAllowList = _scriptOptions ? . Value ? . Functions ;
0 commit comments