@@ -939,6 +939,48 @@ public async Task ReceivesInboundEvent_FunctionLoadResponse()
939
939
Assert . True ( traces . Any ( m => string . Equals ( m . FormattedMessage , "Received FunctionLoadResponse for function: 'js1' with functionId: 'TestFunctionId1'." ) ) , "FunctionLoadResponse TestFunctionId1" ) ;
940
940
}
941
941
942
+ [ Fact ]
943
+ public async Task Receives_Individual_FunctionLoadResponses_Parallel ( )
944
+ {
945
+ await CreateDefaultWorkerChannel ( ) ;
946
+
947
+ var startStreamMessage = new StreamingMessage ( )
948
+ {
949
+ StartStream = new StartStream ( )
950
+ {
951
+ WorkerId = _workerId
952
+ }
953
+ } ;
954
+
955
+ var rpcEvent = new GrpcEvent ( _workerId , startStreamMessage ) ;
956
+ _workerChannel . SendWorkerInitRequest ( rpcEvent ) ;
957
+
958
+ var functionMetadataList = GetTestFunctionsList ( "node" , numberOfFunctions : 250 ) ;
959
+ _workerChannel . SetupFunctionInvocationBuffers ( functionMetadataList ) ;
960
+ _workerChannel . SendFunctionLoadRequests ( managedDependencyOptions : null , TimeSpan . FromSeconds ( 1 ) ) ;
961
+
962
+ var allFunctionIdsAndNames = functionMetadataList . Select ( f => new { Id = f . Properties [ "FunctionId" ] . ToString ( ) , f . Name } ) . ToList ( ) ;
963
+
964
+ // Send function load responses for each function, not necessarily in the order the load requests were sent.
965
+ var publishFunctionLoadResponseTasks = allFunctionIdsAndNames . Select ( function =>
966
+ Task . Run ( ( ) => _testFunctionRpcService . PublishFunctionLoadResponseEvent ( function . Id ) ) ) ;
967
+
968
+ await Task . WhenAll ( publishFunctionLoadResponseTasks ) ;
969
+
970
+ await TestHelpers . Await ( ( ) =>
971
+ {
972
+ return _logger . GetLogMessages ( ) . Count ( m => m . FormattedMessage . StartsWith ( "Received FunctionLoadResponse" ) ) == allFunctionIdsAndNames . Count ;
973
+ } ) ;
974
+
975
+ var traces = _logger . GetLogMessages ( ) ;
976
+
977
+ foreach ( var function in allFunctionIdsAndNames )
978
+ {
979
+ Assert . True ( traces . Any ( m => string . Equals ( m . FormattedMessage , $ "Setting up FunctionInvocationBuffer for function: '{ function . Name } ' with functionId: '{ function . Id } '") ) , $ "setup { function . Id } ") ;
980
+ Assert . True ( traces . Any ( m => string . Equals ( m . FormattedMessage , $ "Received FunctionLoadResponse for function: '{ function . Name } ' with functionId: '{ function . Id } '.") ) , $ "FunctionLoadResponse { function . Id } ") ;
981
+ }
982
+ }
983
+
942
984
[ Fact ]
943
985
public async Task ReceivesInboundEvent_Failed_FunctionLoadResponses ( )
944
986
{
@@ -1489,41 +1531,7 @@ await TestHelpers.Await(() => GetInvocationLogs().Length == logLoop,
1489
1531
1490
1532
private static IEnumerable < FunctionMetadata > GetTestFunctionsList ( string runtime , bool addWorkerProperties = false )
1491
1533
{
1492
- var metadata1 = new FunctionMetadata ( )
1493
- {
1494
- Language = runtime ,
1495
- Name = "js1"
1496
- } ;
1497
-
1498
- metadata1 . SetFunctionId ( "TestFunctionId1" ) ;
1499
- metadata1 . Properties . Add ( LogConstants . CategoryNameKey , "testcat1" ) ;
1500
- metadata1 . Properties . Add ( ScriptConstants . LogPropertyHostInstanceIdKey , "testhostId1" ) ;
1501
-
1502
- if ( addWorkerProperties )
1503
- {
1504
- metadata1 . Properties . Add ( "worker.functionId" , "fn1" ) ;
1505
- }
1506
-
1507
- var metadata2 = new FunctionMetadata ( )
1508
- {
1509
- Language = runtime ,
1510
- Name = "js2" ,
1511
- } ;
1512
-
1513
- metadata2 . SetFunctionId ( "TestFunctionId2" ) ;
1514
- metadata2 . Properties . Add ( LogConstants . CategoryNameKey , "testcat2" ) ;
1515
- metadata2 . Properties . Add ( ScriptConstants . LogPropertyHostInstanceIdKey , "testhostId2" ) ;
1516
-
1517
- if ( addWorkerProperties )
1518
- {
1519
- metadata2 . Properties . Add ( "WORKER.functionId" , "fn2" ) ;
1520
- }
1521
-
1522
- return new List < FunctionMetadata > ( )
1523
- {
1524
- metadata1 ,
1525
- metadata2
1526
- } ;
1534
+ return GetTestFunctionsList ( runtime , numberOfFunctions : 2 , addWorkerProperties ) ;
1527
1535
}
1528
1536
1529
1537
public static ScriptInvocationContext GetTestScriptInvocationContext ( Guid invocationId , TaskCompletionSource < ScriptInvocationResult > resultSource ,
@@ -1548,6 +1556,33 @@ public static ScriptInvocationContext GetTestScriptInvocationContext(Guid invoca
1548
1556
} ;
1549
1557
}
1550
1558
1559
+ private static List < FunctionMetadata > GetTestFunctionsList ( string runtime , int numberOfFunctions , bool addWorkerProperties = false )
1560
+ {
1561
+ var functions = new List < FunctionMetadata > ( ) ;
1562
+
1563
+ for ( int i = 1 ; i <= numberOfFunctions ; i ++ )
1564
+ {
1565
+ var metadata = new FunctionMetadata ( )
1566
+ {
1567
+ Language = runtime ,
1568
+ Name = $ "js{ i } "
1569
+ } ;
1570
+
1571
+ metadata . SetFunctionId ( $ "TestFunctionId{ i } ") ;
1572
+ metadata . Properties . Add ( LogConstants . CategoryNameKey , $ "testcat1") ;
1573
+ metadata . Properties . Add ( ScriptConstants . LogPropertyHostInstanceIdKey , $ "testhostId1") ;
1574
+
1575
+ if ( addWorkerProperties )
1576
+ {
1577
+ metadata . Properties . Add ( "worker.functionId" , $ "fn{ i } ") ;
1578
+ }
1579
+
1580
+ functions . Add ( metadata ) ;
1581
+ }
1582
+
1583
+ return functions ;
1584
+ }
1585
+
1551
1586
/// <summary>
1552
1587
/// The <see cref="ScriptInvocationContext"/> would contain inputs that can be transferred over shared memory.
1553
1588
/// </summary>
0 commit comments