public async Task SendToRules(int taskID, bool responsive = true) { using var scope = ServiceActivator.GetScope(); var adapter = scope.ServiceProvider.GetRequiredService <IConnectionToRulesManagerAdapter>(); var args = new ConnectionToRulesManagerAdapterArgs(Connection, toRules, cache, this); await adapter.SendToRules(taskID, args, responsive); }
public async Task SendToRules(int taskID, ConnectionToRulesManagerAdapterArgs args, bool responsive = true) { var Connection = args.Connection; var toRules = args.toRules; var cache = args.cache; IConnectionRoutedCacheManager connectionRoutedCacheManager = args.connectionRoutedCacheManager; Throw.IfNull(Connection); var taskInfo = $"task: {taskID} connection: {Connection.name}"; // RoutedItem[] temp; _logger.Log(LogLevel.Debug, $"{taskInfo} Entering SendToRules."); try { do { RoutedItem routedItem = null; var count = 0; // bool newItems = false; // lock (toRules) // { // newItems = toRules.Any(e => e.attempts == 0); // } // if (count == 0 || !newItems) // { // bool success = await ToRulesSignal.WaitAsync(LITE.profile.kickoffInterval, LITETask.cts.Token).ConfigureAwait(false); // } // lock (toRules) // { // temp = toRules.ToArray(); // } //send everything in toRules // foreach (var routedItem in temp) // { // if (LITETask.cts.Token.IsCancellationRequested) // { routedItem = toRules.Take(_taskManager.cts.Token); //item removed from list prior to processing count = toRules.Count + 1; _logger.Log(LogLevel.Information, $"{taskInfo} toRules: {count} items to transfer."); // if (routedItem.lastAttempt != null && routedItem.lastAttempt < DateTime.Now.AddMinutes(-retryDelayMinutes)) //not attempted lately // { routedItem.attempts++; routedItem.lastAttempt = DateTime.Now; try { if (routedItem.attempts <= Connection.maxAttempts) { // shb 2019-03-15 BOUR-85 to support intelligent routing of items based on pre-determined routing info // EX: hl7 has the routing info while subsequent dicom items do not // Order of precedence // 0.5) No caching for request / response, done elsewhere // 1) No routing info - use connection - based rules // 2) Prior routing info for patientID and accession # - use provider routing rules // 3) Address - oriented routing in item - override all other rules if (routedItem.id != null && routedItem.type != RoutedItem.Type.RPC) { routedItem = _connectionCache.CacheResponse(Connection, routedItem, cache); //for a dicom/file item to look up prior toConnections of hl7 } var currentProfile = _profileStorage.Current; _rulesManager.Init(currentProfile.rules); routedItem = await _rulesManager.SendToRules(routedItem, _routedItemManager, connectionRoutedCacheManager); if (routedItem != null && routedItem.id != null && routedItem.type != RoutedItem.Type.RPC) { routedItem = _connectionCache.CacheResponse(Connection, routedItem, cache); //for an hl7 to record the toConnections } _routedItemManager.Init(routedItem); _routedItemManager.Dequeue(Connection, toRules, nameof(toRules), error: false); } else { _logger.Log(LogLevel.Warning, $"{taskInfo} {routedItem.RoutedItemMetaFile} exceeded maxAttempts"); _routedItemManager.Init(routedItem); _routedItemManager.Dequeue(Connection, toRules, nameof(toRules), error: true); } } catch (Exception e) { _logger.LogFullException(e, $"{taskInfo} returning item to queue: {routedItem.RoutedItemMetaFile}"); if (routedItem != null) { toRules.Add(routedItem, _taskManager.cts.Token); } } // } // ToRulesSignal.Dispose(); // ToRulesSignal = new SemaphoreSlim(0, 1); // // } // } } while (responsive); } catch (TaskCanceledException) { _logger.Log(LogLevel.Information, $"{taskInfo} Task was canceled."); } catch (Exception e) { _logger.LogFullException(e, taskInfo); } finally { _taskManager.Stop($"{Connection.name}.SendToRules"); } _logger.Log(LogLevel.Debug, $"{taskInfo} Exiting SendToRules."); }