示例#1
0
        protected override async Task SendMessages(IEnumerable <Package> packages)
        {
            var hubContext = await CreateHubContextAsync();

            await Task.WhenAll(from package in packages
                               let index         = ConnectionIndex[package.LocalIndex]
                               let groupIndex    = index % GroupCount
                               let indexInGroup  = index / GroupCount
                               let connection    = package.Connection
                               let data          = package.Data
                               let restApiClient = hubContext
                               where Mode == SignalREnums.GroupConfigMode.Group &&
                               IsSending(indexInGroup, GroupInternalModulo, GroupInternalRemainderBegin, GroupInternalRemainderEnd) &&
                               IsSending(groupIndex, GroupCount, GroupLevelRemainderBegin, GroupLevelRemainderEnd) ||
                               Mode == SignalREnums.GroupConfigMode.Connection &&
                               IsSending(index, Modulo, RemainderBegin, RemainderEnd)
                               select ContinuousSend((GroupName: SignalRUtils.GroupName(Type, index % GroupCount),
                                                      RestApiProvider: restApiClient),
                                                     data,
                                                     SendToGroup,
                                                     TimeSpan.FromMilliseconds(Duration),
                                                     TimeSpan.FromMilliseconds(Interval),
                                                     TimeSpan.FromMilliseconds(1),
                                                     TimeSpan.FromMilliseconds(Interval)));
        }
            async Task StreamingWriter(ChannelWriter <IDictionary <string, object> > writer, IDictionary <string, object> sentData, int count, int streamItemWaiting)
            {
                Exception localException = null;

                try
                {
                    for (var i = 0; i < count; i++)
                    {
                        sentData[SignalRConstants.Timestamp] = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();
                        await writer.WriteAsync(sentData);

                        if (streamItemWaiting > 0)
                        {
                            await Task.Delay(streamItemWaiting);
                        }
                        // Update statistics
                        SignalRUtils.RecordSend(sentData, StatisticsCollector);
                    }
                }
                catch (Exception ex)
                {
                    localException = ex;
                }
                writer.Complete(localException);
            }
示例#3
0
        protected Task Reconnect(
            IDictionary <string, object> stepParameters,
            IDictionary <string, object> pluginParameters,
            IList <IRpcClient> clients)
        {
            // Get parameters
            stepParameters.TryGetTypedValue(SignalRConstants.ConnectionTotal, out int connectionTotal, Convert.ToInt32);
            stepParameters.TryGetTypedValue(SignalRConstants.ConcurrentConnection, out int concurrentConnection, Convert.ToInt32);
            stepParameters.TryGetTypedValue(SignalRConstants.Type, out string type, Convert.ToString);
            // Prepare configuration for each clients
            var packages = clients.Select((client, i) =>
            {
                int currentConcurrentConnection = Util.SplitNumber(concurrentConnection, i, clients.Count);
                (int beg, int end) = Util.GetConnectionRange(connectionTotal, i, clients.Count);
                var data           = new Dictionary <string, object>(stepParameters);
                data[SignalRConstants.ConcurrentConnection] = currentConcurrentConnection > 0 ? currentConcurrentConnection : 1;
                return(new { Client = client, Data = data });
            });

            // Process on clients
            var results = from package in packages select package.Client.QueryAsync(package.Data);

            var  task = Task.WhenAll(results);
            long expectedMilliseconds = SignalRConstants.MillisecondsToWait;

            if (SignalRUtils.FetchTotalConnectionFromContext(pluginParameters, type, out int totalConnections))
            {
                expectedMilliseconds = SignalRUtils.GetTimeoutPerConcurrentSpeed(totalConnections, concurrentConnection);
            }

            return(Util.TimeoutCheckedTask(task, expectedMilliseconds, nameof(Reconnect)));
        }
示例#4
0
        public async Task <IDictionary <string, object> > Do(
            IDictionary <string, object> stepParameters,
            IDictionary <string, object> pluginParameters)
        {
            try
            {
                Log.Information($"Stop connections...");

                // Get parameters
                stepParameters.TryGetTypedValue(SignalRConstants.Type, out string type, Convert.ToString);

                pluginParameters.TryGetTypedValue($"{SignalRConstants.ConnectionStore}.{type}",
                                                  out IList <IHubConnectionAdapter> connections, (obj) => (IList <IHubConnectionAdapter>)obj);
                // Stop the possible scanner
                StopRapirConnectionScanner(stepParameters, pluginParameters);
                // Stop connections
                await Task.WhenAll(from connection in connections
                                   select connection.StopAsync());

                await SignalRUtils.StopNegotiationServer(stepParameters, pluginParameters);

                await SignalRUtils.StopInternalAppServer(stepParameters, pluginParameters);

                return(null);
            }
            catch (Exception ex)
            {
                var message = $"Fail to stop connections: {ex}";
                Log.Error(message);
                throw;
            }
        }
        public Task Do(IDictionary <string, object> stepParameters, IDictionary <string, object> pluginParameters, IList <IRpcClient> clients)
        {
            Log.Information($"Start connections...");

            // Get parameters
            stepParameters.TryGetTypedValue(SignalRConstants.ConcurrentConnection, out int concurrentConnection, Convert.ToInt32);
            stepParameters.TryGetTypedValue(SignalRConstants.Type, out string type, Convert.ToString);
            if (concurrentConnection < clients.Count)
            {
                concurrentConnection = clients.Count;
                var message = $"Concurrent connection {concurrentConnection} should NOT be less than the number of agents {clients.Count}, we force it to be {clients.Count}";
                Log.Warning(message);
            }

            var packages = clients.Select((client, i) =>
            {
                int currentConcurrentConnection = Util.SplitNumber(concurrentConnection, i, clients.Count);
                var data = new Dictionary <string, object>(stepParameters);
                data[SignalRConstants.ConcurrentConnection] = currentConcurrentConnection;
                return(new { Client = client, Data = data });
            });

            var results = from package in packages select package.Client.QueryAsync(package.Data);

            var task = Task.WhenAll(results);
            // we wait until the default timeout reached
            long expectedMilliseconds = SignalRConstants.MillisecondsToWait;

            if (SignalRUtils.FetchTotalConnectionFromContext(pluginParameters, type, out int totalConnections))
            {
                expectedMilliseconds = SignalRUtils.GetTimeoutPerConcurrentSpeed(totalConnections, concurrentConnection);
            }

            return(Util.TimeoutCheckedTask(task, expectedMilliseconds, nameof(StartConnection)));
        }
示例#6
0
        public async Task <IDictionary <string, object> > Do(
            IDictionary <string, object> stepParameters,
            IDictionary <string, object> pluginParameters)
        {
            try
            {
                Log.Information($"Create connections...");
                if (SignalRUtils.isUsingInternalApp(stepParameters))
                {
                    await SignalRUtils.StartInternalAppServer(stepParameters, pluginParameters);

                    // rewrite the url
                    stepParameters[SignalRConstants.HubUrls] = SignalRConstants.LocalhostUrl;
                }

                SignalRUtils.SlaveCreateConnection(stepParameters, pluginParameters, ClientType.AspNetCore);
                return(null);
            }
            catch (Exception ex)
            {
                var message = $"Fail to create connections: {ex}";
                Log.Error(message);
                throw;
            }
        }
示例#7
0
        private double GetLargeLatencyPercentage(IDictionary <string, long> data, long latencyMax)
        {
            var largeLatencyMessageCount = data[SignalRUtils.MessageGreaterOrEqualTo(latencyMax)];
            var receivedMessageCount     = data[SignalRConstants.StatisticsMessageReceived];

            return((double)largeLatencyMessageCount / receivedMessageCount);
        }
示例#8
0
        private async Task DirectConnectionJoinGroup(string connectionString)
        {
            var serviceManager = new ServiceManagerBuilder().WithOptions(option =>
            {
                option.ConnectionString     = connectionString;
                option.ServiceTransportType = ServiceTransportType.Transient;
            }).Build();

            var hubContext = await serviceManager.CreateHubContextAsync(SignalRConstants.DefaultRestHubName);

            await SignalRUtils.JoinGroupForConnection(
                _totalConnection,
                _groupCount,
                _connectionIndex,
                async (i, g) =>
            {
                var userId = SignalRUtils.GenClientUserIdFromConnectionIndex(_connectionIndex[i]);
                try
                {
                    await hubContext.UserGroups.AddToGroupAsync(
                        userId,
                        SignalRUtils.GroupName(_type, g));
                    _statisticsCollector.IncreaseJoinGroupSuccess();
                }
                catch (Exception e)
                {
                    _statisticsCollector.IncreaseJoinGroupFail();
                    Log.Error($"Fail to join group: {e.Message}");
                }
            });
        }
示例#9
0
        public async Task <IDictionary <string, object> > Do(
            IDictionary <string, object> stepParameters,
            IDictionary <string, object> pluginParameters)
        {
            try
            {
                Log.Information($"Dispose connections...");

                // Get parameters
                stepParameters.TryGetTypedValue(SignalRConstants.Type, out string type, Convert.ToString);
                pluginParameters.TryGetTypedValue($"{SignalRConstants.ConnectionStore}.{type}",
                                                  out IList <IHubConnectionAdapter> connections, (obj) => (IList <IHubConnectionAdapter>)obj);
                // Dispose HttpClients
                SignalRUtils.DiposeAllHttpClient(stepParameters, pluginParameters);
                // Dispose connections
                await Task.WhenAll(from connection in connections
                                   select connection.DisposeAsync());

                return(null);
            }
            catch (Exception ex)
            {
                var message = $"Fail to dispose connections: {ex}";
                Log.Error(message);
                throw;
            }
        }
示例#10
0
 protected void UpdateStatistics(
     StatisticsCollector statisticsCollector,
     int sendingStep)
 {
     SignalRUtils.ResetCounters(statisticsCollector);
     UpdateEpoch(statisticsCollector);
     SetSendingStep(statisticsCollector, sendingStep);
 }
示例#11
0
        public async Task Do(IDictionary <string, object> stepParameters, IDictionary <string, object> pluginParameters, IList <IRpcClient> clients)
        {
            Log.Information($"Start to conditional stop...");

            // Get parameters
            stepParameters.TryGetTypedValue(SignalRConstants.Type, out string type, Convert.ToString);
            stepParameters.TryGetTypedValue(SignalRConstants.CriteriaMaxFailConnectionPercentage,
                                            out double criteriaMaxFailConnectionPercentage, Convert.ToDouble);
            stepParameters.TryGetTypedValue(SignalRConstants.CriteriaMaxFailConnectionAmount,
                                            out int criteriaMaxFailConnectionAmount, Convert.ToInt32);
            stepParameters.TryGetTypedValue(SignalRConstants.CriteriaMaxFailSendingPercentage,
                                            out double criteriaMaxFailSendingPercentage, Convert.ToDouble);

            // Get context
            pluginParameters.TryGetTypedValue($"{SignalRConstants.LatencyStep}.{type}",
                                              out long latencyStep, Convert.ToInt64);
            pluginParameters.TryGetTypedValue($"{SignalRConstants.LatencyMax}.{type}",
                                              out long latencyMax, Convert.ToInt64);

            var results = await Task.WhenAll(from client in clients
                                             select client.QueryAsync(stepParameters));

            // Merge statistics
            var merged = SignalRUtils.MergeStatistics(results, latencyMax, latencyStep);

            merged.TryGetTypedValue(SignalRConstants.StatisticsConnectionConnectSuccess,
                                    out long connectionSuccess, Convert.ToInt64);
            merged.TryGetTypedValue(SignalRConstants.StatisticsConnectionConnectFail,
                                    out long connectionFail, Convert.ToInt64);

            var connectionTotal          = connectionSuccess + connectionFail;
            var connectionFailPercentage = (double)connectionFail / connectionTotal;
            var largeLatencyPercentage   = GetLargeLatencyPercentage(merged, latencyMax);

            if (connectionFailPercentage > criteriaMaxFailConnectionPercentage)
            {
                var message = $"Connection fail percentage {connectionFailPercentage * 100}%" +
                              $" is greater than criteria {criteriaMaxFailConnectionPercentage * 100}%, stop benchmark";
                Log.Warning(message);
                throw new Exception(message);
            }
            if (connectionFail > criteriaMaxFailConnectionAmount)
            {
                var message = $"Connection fail amount {connectionFail}" +
                              $"is greater than {criteriaMaxFailConnectionAmount}, stop benchmark";
                Log.Warning(message);
                throw new Exception(message);
            }
            if (largeLatencyPercentage > criteriaMaxFailSendingPercentage)
            {
                var message = $"The percentage {largeLatencyPercentage * 100}%" +
                              $"of Sending latency greater than {latencyMax}" +
                              $" ms is larger than {criteriaMaxFailSendingPercentage * 100}%, stop benchmark";
                Log.Warning(message);
                throw new Exception(message);
            }
        }
示例#12
0
        public Task Do(
            IDictionary <string, object> stepParameters,
            IDictionary <string, object> pluginParameters,
            IList <IRpcClient> clients)
        {
            Log.Information($"Create AspNet connections...");
            var ret = SignalRUtils.MasterCreateConnection(stepParameters, pluginParameters, clients);

            return(ret);
        }
        public Task Do(IDictionary <string, object> stepParameters, IDictionary <string, object> pluginParameters, IList <IRpcClient> clients)
        {
            Log.Information($"Stop connections...");

            var data = new Dictionary <string, object>();

            SignalRUtils.AddMethodAndType(data, stepParameters);

            return(Task.WhenAll(from client in clients
                                select client.QueryAsync(data)));
        }
        public void TestTryGetBatchMode()
        {
            var dic = new Dictionary <string, object>();

            SignalRUtils.TryGetBatchMode(
                dic,
                out string batchConfigMode,
                out int batchWaitMilliSeconds,
                out SignalREnums.BatchMode mode);
            Assert.Equal(batchConfigMode, SignalRConstants.DefaultBatchMode);
        }
示例#15
0
        protected async Task LatencyEventerCallback(
            IDictionary <string, object> stepParameters,
            IDictionary <string, object> pluginParameters, IList <IRpcClient> clients)
        {
            var results = await Task.WhenAll(from client in clients
                                             select client.QueryAsync(stepParameters));

            // Merge statistics
            var merged = SignalRUtils.MergeStatistics(results, _latencyMax, _latencyStep);

            PrintAndSave(merged);
        }
示例#16
0
        public async Task <IDictionary <string, object> > Do(
            IDictionary <string, object> stepParameters,
            IDictionary <string, object> pluginParameters)
        {
            try
            {
                Log.Information($"Join groups...");

                // Get parameters
                stepParameters.TryGetTypedValue(SignalRConstants.Type,
                                                out _type, Convert.ToString);
                stepParameters.TryGetTypedValue(SignalRConstants.GroupCount,
                                                out _groupCount, Convert.ToInt32);
                stepParameters.TryGetTypedValue(SignalRConstants.ConnectionTotal,
                                                out _totalConnection, Convert.ToInt32);

                if (_totalConnection % _groupCount != 0)
                {
                    //throw new Exception("Not supported: Total connections cannot be divided by group count");
                    Log.Warning($"groups do not have equal members because total connections {_totalConnection} cannot be divided by group count {_groupCount}");
                }

                SignalRUtils.SaveGroupInfoToContext(pluginParameters, _type, _groupCount, _totalConnection);
                // Get context
                pluginParameters.TryGetTypedValue($"{SignalRConstants.ConnectionStore}.{_type}",
                                                  out _connections, (obj) => (IList <IHubConnectionAdapter>)obj);
                pluginParameters.TryGetTypedValue($"{SignalRConstants.StatisticsStore}.{_type}",
                                                  out _statisticsCollector, obj => (StatisticsCollector)obj);
                pluginParameters.TryGetTypedValue($"{SignalRConstants.ConnectionIndex}.{_type}",
                                                  out _connectionIndex, (obj) => (List <int>)obj);

                // Reset counters
                SignalRUtils.ResetCounters(_statisticsCollector);
                // Join group
                var connectionType = SignalRUtils.GetClientTypeFromContext(pluginParameters, _type);
                if (connectionType == SignalREnums.ClientType.DirectConnect)
                {
                    var connectionString = SignalRUtils.FetchConnectionStringFromContext(pluginParameters, _type);
                    await DirectConnectionJoinGroup(connectionString);
                }
                else
                {
                    await NormalConnectionJoinGroup();
                }
                return(null);
            }
            catch (Exception ex)
            {
                var message = $"Fail to join group: {ex}";
                Log.Error(message);
                throw;
            }
        }
示例#17
0
 public static void SetCallback(
     IList <IHubConnectionAdapter> connections,
     StatisticsCollector statisticsCollector)
 {
     foreach (var connection in connections)
     {
         connection.On(SignalRConstants.RecordLatencyCallbackName, (IDictionary <string, object> data) =>
         {
             var receiveTimestamp = Util.Timestamp();
             data.TryGetTypedValue(SignalRConstants.Timestamp, out long sendTimestamp, Convert.ToInt64);
             var latency = receiveTimestamp - sendTimestamp;
             statisticsCollector.RecordLatency(latency);
             SignalRUtils.RecordRecvSize(data, statisticsCollector);
         });
示例#18
0
        private async Task DirectConnectionLeaveGroup(string connectionString)
        {
            var serviceManager = new ServiceManagerBuilder().WithOptions(option =>
            {
                option.ConnectionString     = connectionString;
                option.ServiceTransportType = ServiceTransportType.Transient;
            }).Build();

            var hubContext = await serviceManager.CreateHubContextAsync(SignalRConstants.DefaultRestHubName);

            if (_connections.Count >= _groupCount)
            {
                for (var i = 0; i < _connections.Count; i++)
                {
                    var userId = SignalRUtils.GenClientUserIdFromConnectionIndex(_connectionIndex[i]);
                    try
                    {
                        await hubContext.UserGroups.RemoveFromGroupAsync(userId,
                                                                         SignalRUtils.GroupName(_type, _connectionIndex[i] % _groupCount));

                        _statisticsCollector.IncreaseLeaveGroupSuccess();
                    }
                    catch (Exception e)
                    {
                        _statisticsCollector.IncreaseLeaveGroupFail();
                        Log.Error($"Fail to leave group: {e.Message}");
                    }
                }
            }
            else
            {
                for (var i = 0; i < _groupCount; i++)
                {
                    var userId = SignalRUtils.GenClientUserIdFromConnectionIndex(i);
                    try
                    {
                        await hubContext.UserGroups.RemoveFromGroupAsync(
                            userId,
                            SignalRUtils.GroupName(_type, i));

                        _statisticsCollector.IncreaseLeaveGroupSuccess();
                    }
                    catch (Exception e)
                    {
                        _statisticsCollector.IncreaseLeaveGroupFail();
                        Log.Error($"Fail to leave group: {e.Message}");
                    }
                }
            }
        }
示例#19
0
 private async Task NormalConnectionJoinGroup()
 {
     await SignalRUtils.JoinGroupForConnection(
         _totalConnection,
         _groupCount,
         _connectionIndex,
         async (i, g) =>
     {
         await SignalRUtils.JoinToGroup(
             _connections[i],
             SignalRUtils.GroupName(_type, g),
             _statisticsCollector);
     });
 }
示例#20
0
        protected async Task ConnectionStatEventerCallback(
            IDictionary <string, object> stepParameters,
            IDictionary <string, object> pluginParameters, IList <IRpcClient> clients)
        {
            var results = await Task.WhenAll(from client in clients
                                             select client.QueryAsync(stepParameters));

            // Merge statistics
            var merged = SignalRUtils.MergeStatistics(results, _latencyMax, _latencyStep);
            var connectionStatMerged = SignalRUtils.MergeConnectionStatistics(results, _percentileList.ToArray());

            merged = merged.Union(connectionStatMerged).ToDictionary(entry => entry.Key, entry => entry.Value);
            PrintAndSave(merged);
        }
        public void RecordLatency(long latency)
        {
            var index      = latency / LatencyStep;
            var upperBound = (index + 1) * LatencyStep;

            if (upperBound <= LatencyMax)
            {
                _statistics.AddOrUpdate(SignalRUtils.MessageLessThan(upperBound), 1, (k, v) => v + 1);
            }
            else
            {
                _statistics.AddOrUpdate(SignalRUtils.MessageGreaterOrEqualTo(LatencyMax), 1, (k, v) => v + 1);
            }
        }
示例#22
0
        public async Task <IDictionary <string, object> > Do(
            IDictionary <string, object> stepParameters,
            IDictionary <string, object> pluginParameters)
        {
            try
            {
                Log.Information($"Leave groups...");

                // Get parameters
                stepParameters.TryGetTypedValue(SignalRConstants.Type, out _type, Convert.ToString);
                stepParameters.TryGetTypedValue(SignalRConstants.GroupCount, out _groupCount, Convert.ToInt32);
                stepParameters.TryGetTypedValue(SignalRConstants.ConnectionTotal, out int totalConnection, Convert.ToInt32);

                if (totalConnection % _groupCount != 0)
                {
                    throw new Exception("Not supported: Total connections cannot be divided by group count");
                }

                // Get context
                pluginParameters.TryGetTypedValue($"{SignalRConstants.ConnectionStore}.{_type}",
                                                  out _connections, (obj) => (IList <IHubConnectionAdapter>)obj);
                pluginParameters.TryGetTypedValue($"{SignalRConstants.StatisticsStore}.{_type}",
                                                  out _statisticsCollector, obj => (StatisticsCollector)obj);
                pluginParameters.TryGetTypedValue($"{SignalRConstants.ConnectionIndex}.{_type}",
                                                  out _connectionIndex, (obj) => (List <int>)obj);

                // Not reset counters because typically this step is followed the last sending step.
                // We do not want to clear the last sending step's sending statistics
                // Leave group
                var connectionType = SignalRUtils.GetClientTypeFromContext(pluginParameters, _type);
                if (connectionType == SignalREnums.ClientType.DirectConnect)
                {
                    var connectionString = SignalRUtils.FetchConnectionStringFromContext(pluginParameters, _type);
                    await DirectConnectionLeaveGroup(connectionString);
                }
                else
                {
                    await NormalConnectionLeaveGroup();
                }
                return(null);
            }
            catch (Exception ex)
            {
                var message = $"Fail to leave group: {ex}";
                Log.Error(message);
                throw;
            }
        }
示例#23
0
        public async Task <IDictionary <string, object> > Do(IDictionary <string, object> stepParameters, IDictionary <string, object> pluginParameters)
        {
            try
            {
                Log.Information($"Start connections...");

                // Get parameters
                stepParameters.TryGetTypedValue(SignalRConstants.ConcurrentConnection,
                                                out int concurrentConnection, Convert.ToInt32);
                stepParameters.TryGetTypedValue(SignalRConstants.Type,
                                                out string type, Convert.ToString);
                pluginParameters.TryGetTypedValue($"{SignalRConstants.ConnectionStore}.{type}",
                                                  out IList <IHubConnectionAdapter> connections, (obj) => (IList <IHubConnectionAdapter>)obj);
                pluginParameters.TryGetTypedValue($"{SignalRConstants.StatisticsStore}.{type}",
                                                  out _statisticsCollector, obj => (StatisticsCollector)obj);
                SignalRUtils.FilterOnConnectedNotification(pluginParameters, type);
                // The following get connection Id needs the concurrent connection value
                SignalRUtils.SaveConcurrentConnectionCountToContext(
                    pluginParameters,
                    type,
                    concurrentConnection);

                var sw = new Stopwatch();
                sw.Start();
                Log.Information($"{DateTime.Now.ToString("yyyyMMddHHmmss")} Start connection");
                try
                {
                    await BatchConnect(
                        stepParameters,
                        pluginParameters,
                        connections,
                        concurrentConnection);
                }
                finally
                {
                    sw.Stop();
                    Log.Information($"{DateTime.Now.ToString("yyyyMMddHHmmss")} Finishing connection {connections.Count} with {sw.ElapsedMilliseconds} ms");
                }
                return(null);
            }
            catch (Exception ex)
            {
                var message = $"Fail to start connections: {ex}";
                Log.Error(message);
                throw;
            }
        }
示例#24
0
 public Task <IDictionary <string, object> > Do(
     IDictionary <string, object> stepParameters,
     IDictionary <string, object> pluginParameters)
 {
     try
     {
         Log.Information($"Create connections...");
         SignalRUtils.SlaveCreateConnection(stepParameters, pluginParameters, ClientType.AspNet);
         return(Task.FromResult <IDictionary <string, object> >(null));
     }
     catch (Exception ex)
     {
         var message = $"Fail to create connections: {ex}";
         Log.Error(message);
         throw;
     }
 }
示例#25
0
        protected override async Task <IDictionary <string, object> > SimpleScenarioSend(
            IDictionary <string, object> stepParameters,
            IDictionary <string, object> pluginParameters,
            string callbackMethod)
        {
            try
            {
                Log.Information($"Start {GetType().Name}...");

                LoadParametersAndContext(stepParameters, pluginParameters);

                // Generate necessary data
                var data = new Dictionary <string, object>
                {
                    { SignalRConstants.MessageBlob, SignalRUtils.GenerateRandomData(MessageSize) } // message payload
                };

                // Reset counters
                UpdateStatistics(StatisticsCollector, RemainderEnd);

                // Send messages
                await Task.WhenAll(from i in Enumerable.Range(0, Connections.Count)
                                   where ConnectionIndex[i] % Modulo >= RemainderBegin && ConnectionIndex[i] % Modulo < RemainderEnd
                                   select ContinuousSend((Connection: Connections[i],
                                                          LocalIndex: i,
                                                          CallbackMethod: callbackMethod,
                                                          StreamItemsCount,
                                                          StreamItemInterval),
                                                         data,
                                                         StreamingBaseSendAsync,
                                                         TimeSpan.FromMilliseconds(Duration),
                                                         TimeSpan.FromMilliseconds(Interval),
                                                         TimeSpan.FromMilliseconds(1),
                                                         TimeSpan.FromMilliseconds(Interval)));

                Log.Information($"Finish {GetType().Name} {RemainderEnd}");
                return(null);
            }
            catch (Exception ex)
            {
                var message = $"Fail to {GetType().Name}: {ex}";
                Log.Error(message);
                throw;
            }
        }
示例#26
0
        public async Task <IDictionary <string, object> > Do(IDictionary <string, object> stepParameters, IDictionary <string, object> pluginParameters)
        {
            try
            {
                Log.Information($"Send {GetType().Name}...");

                LoadParametersAndContext(stepParameters, pluginParameters);
                // Get parameters
                stepParameters.TryGetTypedValue(SignalRConstants.ConnectionIdStore, out string[] connectionIds,
                                                obj => Convert.ToString(obj).Split(' '));

                // Generate necessary data
                var messageBlob = SignalRUtils.GenerateRandomData(MessageSize);

                // Reset counters
                UpdateStatistics(StatisticsCollector, RemainderEnd);

                // Send messages
                await Task.WhenAll(from i in Enumerable.Range(0, Connections.Count)
                                   let data = new Dictionary <string, object>
                {
                    { SignalRConstants.MessageBlob, messageBlob },                    // message payload
                    { SignalRConstants.ConnectionId, connectionIds[i] }
                }
                                   where ConnectionIndex[i] % Modulo >= RemainderBegin && ConnectionIndex[i] % Modulo < RemainderEnd
                                   select ContinuousSend((Connection: Connections[i],
                                                          LocalIndex: i,
                                                          CallbackMethod: SignalRConstants.SendToClientCallbackName),
                                                         data,
                                                         BaseSendAsync,
                                                         TimeSpan.FromMilliseconds(Duration),
                                                         TimeSpan.FromMilliseconds(Interval),
                                                         TimeSpan.FromMilliseconds(1),
                                                         TimeSpan.FromMilliseconds(Interval)));

                Log.Information($"Finish {GetType().Name} {RemainderEnd}");
                return(null);
            }
            catch (Exception ex)
            {
                var message = $"Fail to send to client: {ex}";
                Log.Error(message);
                throw;
            }
        }
示例#27
0
        public async Task BatchConnect(
            IDictionary <string, object> stepParameters,
            IDictionary <string, object> pluginParameters,
            IList <IHubConnectionAdapter> connections,
            int concurrentConnection)
        {
            SignalRUtils.TryGetBatchMode(
                stepParameters,
                out string batchConfigMode,
                out int batchWaitMilliSeconds,
                out SignalREnums.BatchMode mode);
            var packages = (from i in Enumerable.Range(0, connections.Count())
                            where connections[i].GetStat() == SignalREnums.ConnectionInternalStat.Init
                            select(Connection: connections[i], LocalIndex: i)).ToList();
            // 100 milliseconds is the default fine-granularity
            var period = SignalRConstants.RateLimitDefaultGranularity;
            var factor = 1000 / period;
            var fillTokenPerDuration = concurrentConnection > factor ? concurrentConnection / factor : 1;

            switch (mode)
            {
            case SignalREnums.BatchMode.ExtLimitRatePress:
                await Util.ExternalRateLimitBatchProcess(packages, SignalRUtils.StartConnect,
                                                         concurrentConnection, fillTokenPerDuration, period);

                break;

            case SignalREnums.BatchMode.LimitRatePress:
                await Util.RateLimitBatchProces(packages,
                                                SignalRUtils.StartConnect, concurrentConnection, fillTokenPerDuration, period);

                break;

            case SignalREnums.BatchMode.HighPress:
                await Util.BatchProcess(packages, SignalRUtils.StartConnect, concurrentConnection);

                break;

            case SignalREnums.BatchMode.LowPress:
                await Util.LowPressBatchProcess(packages, SignalRUtils.StartConnect,
                                                concurrentConnection, batchWaitMilliSeconds);

                break;
            }
        }
示例#28
0
 private async Task NormalConnectionLeaveGroup()
 {
     if (_connections.Count >= _groupCount)
     {
         await Task.WhenAll(from i in Enumerable.Range(0, _connections.Count)
                            select SignalRUtils.LeaveFromGroup(_connections[i],
                                                               SignalRUtils.GroupName(_type,
                                                                                      _connectionIndex[i] % _groupCount),
                                                               _statisticsCollector));
     }
     else
     {
         var connectionCount = _connections.Count;
         await Task.WhenAll(from i in Enumerable.Range(0, _groupCount)
                            select SignalRUtils.LeaveFromGroup(_connections[i % connectionCount],
                                                               SignalRUtils.GroupName(_type, i),
                                                               _statisticsCollector));
     }
 }
示例#29
0
        public async Task <IDictionary <string, object> > Do(
            IDictionary <string, object> stepParameters,
            IDictionary <string, object> pluginParameters)
        {
            try
            {
                // Here allow manually evaluate the "send" latency if "RecordLatency" callback is not registered
                HideRecordLatency = SignalRUtils.HideMessageRoundTripLatency(stepParameters, pluginParameters);
                await RunRest(stepParameters, pluginParameters);

                return(null);
            }
            catch (Exception ex)
            {
                var message = $"Fail to {GetType().Name}: {ex}";
                Log.Error(message);
                throw;
            }
        }
示例#30
0
        public Task <IDictionary <string, object> > Do(
            IDictionary <string, object> stepParameters,
            IDictionary <string, object> pluginParameters)
        {
            stepParameters.TryGetTypedValue(SignalRConstants.Type,
                                            out string type, Convert.ToString);
            pluginParameters.TryGetTypedValue($"{SignalRConstants.ConnectionStore}.{type}",
                                              out IList <IHubConnectionAdapter> connections, (obj) => (IList <IHubConnectionAdapter>)obj);

            if (stepParameters.TryGetValue(SignalRConstants.ActionAfterConnect, out _))
            {
                stepParameters.TryGetTypedValue(SignalRConstants.ActionAfterConnect,
                                                out string postAction, Convert.ToString);
                if (Enum.TryParse(postAction, out SignalREnums.ActionAfterConnection action))
                {
                    _action = action;
                }
            }
            _concurrentConnection =
                SignalRUtils.FetchConcurrentConnectionCountFromContext(
                    pluginParameters,
                    type,
                    connections.Count);
            _type = type;

            // register the CTS to control the connector repairer.
            var cts = new CancellationTokenSource();

            pluginParameters[$"{SignalRConstants.RepairConnectionCTS}.{type}"] = cts;
            _context = pluginParameters;
            _        = Task.Run(async() =>
            {
                try
                {
                    await Start(connections, cts);
                }
                catch (Exception e)
                {
                    Log.Error($"Fail to repair the connection: {e.Message}");
                }
            });
            return(Task.FromResult <IDictionary <string, object> >(null));;
        }