private void SetFunctionCurrentConcurrency(ConcurrencyManager concurrencyManager, string functionId, int concurrency) { var concurrencyStatus = concurrencyManager.GetStatus(functionId); var propertyInfo = typeof(ConcurrencyStatus).GetProperty("CurrentConcurrency", BindingFlags.Instance | BindingFlags.Public); propertyInfo.SetValue(concurrencyStatus, concurrency); }
/// <summary> /// Check current concurrency levels for this function, and adjust processor concurrency as necessary. /// </summary> public void UpdateConcurrency() { if (!_messagesProcessedSinceLastConcurrencyUpdate) { // if the function is currently inactive, we can skip the concurrency update check return; } _messagesProcessedSinceLastConcurrencyUpdate = false; // below we'll dynamically update the processor with new concurrency values if any // need to be changed var concurrencyStatus = _concurrencyManager.GetStatus(_functionId); var currentConcurrency = concurrencyStatus.CurrentConcurrency; if (_isSessionsEnabled) { var sessionProcessor = _sessionMessageProcessor.Value.Processor; if (currentConcurrency != sessionProcessor.MaxConcurrentSessions) { // Per session call concurrency is limited to 1 meaning sessions are 1:1 with invocations. // So we can scale MaxConcurrentSessions 1:1 with CurrentConcurrency. sessionProcessor.UpdateConcurrency(currentConcurrency, sessionProcessor.MaxConcurrentCallsPerSession); } } else { var processor = _messageProcessor.Value.Processor; if (currentConcurrency != processor.MaxConcurrentCalls) { processor.UpdateConcurrency(currentConcurrency); } } }
internal int GetMessageReceiveCount() { int numMessagesToReceive = _queueProcessor.QueuesOptions.BatchSize; if (_concurrencyManager != null && _concurrencyManager.Enabled) { // When not using DC, WaitForNewBatchThreshold cleans up tasks as they complete. // When using DC we need to also do cleanup of completed tasks, particularly // before we use the count of pending tasks in the calculation below. var completedTasks = _processing.Where(p => p.IsCompleted).ToArray(); foreach (var completedTask in completedTasks) { _processing.Remove(completedTask); } // When DynamicConcurrency is enabled, we determine the number of messages to pull // based on the current degree of parallelism for this function and our pending invocation count. var concurrencyStatus = _concurrencyManager.GetStatus(_functionId); int availableInvocationCount = concurrencyStatus.GetAvailableInvocationCount(_processing.Count); numMessagesToReceive = Math.Min(availableInvocationCount, QueuesOptions.MaxBatchSize); } return(numMessagesToReceive); }