@@ -72,6 +72,8 @@ public class ScriptHost : JobHost
72
72
private static readonly Regex FunctionNameValidationRegex = new Regex ( @"^[a-z][a-z0-9_\-]{0,127}$(?<!^host$)" , RegexOptions . Compiled | RegexOptions . IgnoreCase ) ;
73
73
private static readonly Regex ProxyNameValidationRegex = new Regex ( @"[^a-zA-Z0-9_-]" , RegexOptions . Compiled | RegexOptions . IgnoreCase ) ;
74
74
public static readonly string Version = GetAssemblyFileVersion ( typeof ( ScriptHost ) . Assembly ) ;
75
+ internal static readonly int DefaultMaxMessageLengthBytesDynamicSku = 32 * 1024 * 1024 ;
76
+ internal static readonly int DefaultMaxMessageLengthBytes = 128 * 1024 * 1024 ;
75
77
private ScriptSettingsManager _settingsManager ;
76
78
private bool _shutdownScheduled ;
77
79
private ILogger _startupLogger ;
@@ -498,16 +500,22 @@ internal void InitializeFunctionDescriptors(Collection<FunctionMetadata> functio
498
500
_descriptorProviders = new List < FunctionDescriptorProvider > ( ) ;
499
501
if ( string . IsNullOrEmpty ( language ) )
500
502
{
503
+ _startupLogger . LogTrace ( "Adding all the Function descriptors." ) ;
501
504
_descriptorProviders . Add ( new DotNetFunctionDescriptorProvider ( this , ScriptConfig ) ) ;
502
505
_descriptorProviders . Add ( new WorkerFunctionDescriptorProvider ( this , ScriptConfig , _functionDispatcher ) ) ;
503
506
}
504
- else if ( language . Equals ( ScriptConstants . DotNetLanguageWorkerName , StringComparison . OrdinalIgnoreCase ) )
505
- {
506
- _descriptorProviders . Add ( new DotNetFunctionDescriptorProvider ( this , ScriptConfig ) ) ;
507
- }
508
507
else
509
508
{
510
- _descriptorProviders . Add ( new WorkerFunctionDescriptorProvider ( this , ScriptConfig , _functionDispatcher ) ) ;
509
+ _startupLogger . LogTrace ( $ "Adding Function descriptor for language { language } .") ;
510
+ switch ( language . ToLower ( ) )
511
+ {
512
+ case ScriptConstants . DotNetLanguageWorkerName :
513
+ _descriptorProviders . Add ( new DotNetFunctionDescriptorProvider ( this , ScriptConfig ) ) ;
514
+ break ;
515
+ default :
516
+ _descriptorProviders . Add ( new WorkerFunctionDescriptorProvider ( this , ScriptConfig , _functionDispatcher ) ) ;
517
+ break ;
518
+ }
511
519
}
512
520
513
521
Collection < FunctionDescriptor > functions ;
@@ -645,7 +653,7 @@ private JObject ApplyHostConfiguration()
645
653
string sanitizedJson = SanitizeHostJson ( hostConfigObject ) ;
646
654
string readFileMessage = $ "Host configuration file read:{ Environment . NewLine } { sanitizedJson } ";
647
655
648
- ApplyConfiguration ( hostConfigObject , ScriptConfig ) ;
656
+ ApplyConfiguration ( hostConfigObject , ScriptConfig , _startupLogger ) ;
649
657
650
658
if ( _settingsManager . FileSystemIsReadOnly )
651
659
{
@@ -698,7 +706,7 @@ private JObject ApplyHostConfiguration()
698
706
private void InitializeWorkers ( string language )
699
707
{
700
708
var serverImpl = new FunctionRpcService ( EventManager ) ;
701
- var server = new GrpcServer ( serverImpl ) ;
709
+ var server = new GrpcServer ( serverImpl , ScriptConfig . MaxMessageLengthBytes ) ;
702
710
703
711
// TODO: async initialization of script host - hook into startasync method?
704
712
server . StartAsync ( ) . GetAwaiter ( ) . GetResult ( ) ;
@@ -733,7 +741,7 @@ private void InitializeWorkers(string language)
733
741
// TODO: We still have some hard coded languages, so we need to handle them. Remove this switch once we've moved away from that.
734
742
switch ( language . ToLower ( ) )
735
743
{
736
- case ScriptConstants . NodeLanguageWrokerName :
744
+ case ScriptConstants . NodeLanguageWorkerName :
737
745
providers . Add ( new NodeWorkerProvider ( ) ) ;
738
746
break ;
739
747
case ScriptConstants . JavaLanguageWrokerName :
@@ -1405,11 +1413,6 @@ internal Collection<FunctionDescriptor> GetFunctionDescriptors(IEnumerable<Funct
1405
1413
ValidateFunction ( descriptor , httpFunctions ) ;
1406
1414
functionDescriptors . Add ( descriptor ) ;
1407
1415
}
1408
- else
1409
- {
1410
- string functionLanguage = _settingsManager . Configuration [ ScriptConstants . FunctionWorkerRuntimeSettingName ] ;
1411
- throw new ArgumentException ( $ "Could not find a valid provider. { ScriptConstants . FunctionWorkerRuntimeSettingName } Appsetting is set to { functionLanguage } . Check that you have the correct language provider enabled and installed") ;
1412
- }
1413
1416
}
1414
1417
catch ( Exception ex )
1415
1418
{
@@ -1491,7 +1494,7 @@ internal static bool HttpRoutesConflict(HttpTriggerAttribute httpTrigger, HttpTr
1491
1494
return httpTrigger . Methods . Intersect ( otherHttpTrigger . Methods ) . Any ( ) ;
1492
1495
}
1493
1496
1494
- internal static void ApplyConfiguration ( JObject config , ScriptHostConfiguration scriptConfig )
1497
+ internal static void ApplyConfiguration ( JObject config , ScriptHostConfiguration scriptConfig , ILogger logger = null )
1495
1498
{
1496
1499
var hostConfig = scriptConfig . HostConfig ;
1497
1500
@@ -1600,6 +1603,7 @@ internal static void ApplyConfiguration(JObject config, ScriptHostConfiguration
1600
1603
}
1601
1604
}
1602
1605
1606
+ value = null ;
1603
1607
if ( config . TryGetValue ( "functionTimeout" , out value ) )
1604
1608
{
1605
1609
TimeSpan requestedTimeout = TimeSpan . Parse ( ( string ) value , CultureInfo . InvariantCulture ) ;
@@ -1620,10 +1624,44 @@ internal static void ApplyConfiguration(JObject config, ScriptHostConfiguration
1620
1624
}
1621
1625
scriptConfig . HostConfig . FunctionTimeout = ScriptHost . CreateTimeoutConfiguration ( scriptConfig ) ;
1622
1626
1627
+ ApplyLanguageWorkerConfig ( config , scriptConfig , logger ) ;
1623
1628
ApplyLoggerConfig ( config , scriptConfig ) ;
1624
1629
ApplyApplicationInsightsConfig ( config , scriptConfig ) ;
1625
1630
}
1626
1631
1632
+ private static void ApplyLanguageWorkerConfig ( JObject config , ScriptHostConfiguration scriptConfig , ILogger logger )
1633
+ {
1634
+ JToken value = null ;
1635
+ JObject languageWorkerSection = ( JObject ) config [ "languageWorker" ] ;
1636
+ int requestedGrpcMaxMessageLength = ScriptSettingsManager . Instance . IsDynamicSku ? DefaultMaxMessageLengthBytesDynamicSku : DefaultMaxMessageLengthBytes ;
1637
+ if ( languageWorkerSection != null )
1638
+ {
1639
+ if ( languageWorkerSection . TryGetValue ( "maxMessageLength" , out value ) )
1640
+ {
1641
+ int valueInBytes = int . Parse ( ( string ) value ) * 1024 * 1024 ;
1642
+ if ( ScriptSettingsManager . Instance . IsDynamicSku )
1643
+ {
1644
+ string message = $ "Cannot set { nameof ( scriptConfig . MaxMessageLengthBytes ) } on Consumption plan. Default MaxMessageLength: { DefaultMaxMessageLengthBytesDynamicSku } will be used";
1645
+ logger ? . LogWarning ( message ) ;
1646
+ }
1647
+ else
1648
+ {
1649
+ if ( valueInBytes < 0 || valueInBytes > 2000 * 1024 * 1024 )
1650
+ {
1651
+ // Current grpc max message limits
1652
+ string message = $ "MaxMessageLength must be between 4MB and 2000MB.Default MaxMessageLength: { DefaultMaxMessageLengthBytes } will be used";
1653
+ logger ? . LogWarning ( message ) ;
1654
+ }
1655
+ else
1656
+ {
1657
+ requestedGrpcMaxMessageLength = valueInBytes ;
1658
+ }
1659
+ }
1660
+ }
1661
+ }
1662
+ scriptConfig . MaxMessageLengthBytes = requestedGrpcMaxMessageLength ;
1663
+ }
1664
+
1627
1665
internal static void ApplyLoggerConfig ( JObject configJson , ScriptHostConfiguration scriptConfig )
1628
1666
{
1629
1667
scriptConfig . LogFilter = new LogCategoryFilter ( ) ;
0 commit comments