Esempio n. 1
0
 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);
 }
Esempio n. 2
0
        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.");
        }