//methods
        public virtual bool Execute(SignalWrapper <SignalDispatch <TKey> > item)
        {
            if (item.Signal.EventSettingsId == null)
            {
                //SignalDispatch can be provided by ISignalProver without EventSettingsId
                return(true);
            }

            EventSettings <TKey> eventSettings = _eventSettingsQueries.Select(item.Signal.EventSettingsId.Value).Result;

            if (eventSettings == null)
            {
                _logger.LogError(SenderInternalMessages.Common_NoServiceWithKeyFound,
                                 typeof(EventSettings <TKey>), nameof(EventSettings <TKey> .EventSettingsId), item.Signal.EventSettingsId.Value);
                _dispatchQueue.ApplyResult(item, ProcessingResult.NoHandlerFound);
                return(false);
            }

            bool shouldConsolidate = ValidateRequiredProperties(item.Signal, eventSettings);

            if (!shouldConsolidate)
            {
                //Continue processing dispatch without consolidation
                return(true);
            }

            ITemplateDataConsolidator consolidator = MatchConsolidator(item.Signal, eventSettings.ConsolidatorId.Value);

            if (consolidator == null)
            {
                _dispatchQueue.ApplyResult(item, ProcessingResult.NoHandlerFound);
                return(false);
            }

            DispatchTemplate <TKey> dispatchTemplate = eventSettings.Templates == null
                ? null
                : eventSettings.Templates.FirstOrDefault(x => EqualityComparer <TKey> .Default.Equals(x.DispatchTemplateId, item.Signal.DispatchTemplateId.Value));

            if (dispatchTemplate == null)
            {
                _logger.LogError(SenderInternalMessages.Common_NoServiceWithKeyFound,
                                 typeof(DispatchTemplate <TKey>), nameof(DispatchTemplate <TKey> .DispatchTemplateId), item.Signal.DispatchTemplateId.Value);
                _dispatchQueue.ApplyResult(item, ProcessingResult.NoHandlerFound);
                return(false);
            }

            IEnumerable <TemplateData[]> batches = GetTemplateDataBatches(item, consolidator.BatchSize);
            TemplateData consolidatedData        = consolidator.Consolidate(batches);

            dispatchTemplate.Update(item.Signal, consolidatedData);
            item.IsUpdated = true;
            item.IsConsolidationCompleted = true;

            return(true);
        }
示例#2
0
        //methods
        public bool Execute(SignalWrapper <SignalDispatch <TKey> > item)
        {
            ConsolidationLock <TKey> groupLock = _consolidationLockTracker.GetOrAddLock(item.Signal);

            if (groupLock == null)
            {
                //other process cleared consolidation locks table in the middle
                //just repeat processing later
                _dispatchQueue.ApplyResult(item, ProcessingResult.Repeat);
                return(false);
            }

            bool isLockedByCurrentInstance = groupLock.LockedBy == _settings.LockedByInstanceId;

            if (!isLockedByCurrentInstance)
            {
                //this consolidation is handled by other Sender instance.
                //databaes Signal will be removed after consolidation finished but responsible Sender instance.
                return(false);
            }

            bool isConsolidationRoot = EqualityComparer <TKey> .Default.Equals(
                groupLock.ConsolidationRootId, item.Signal.SignalDispatchId);

            if (isConsolidationRoot)
            {
                //lock was created and this dispatch is now consolidation root.
                //can start consolidation.
                return(true);
            }

            bool willBeConsolidatedWithCurrentBatch = item.Signal.CreateDateUtc < groupLock.ConsolidationRootSendDateUtc;

            if (willBeConsolidatedWithCurrentBatch)
            {
                //this dispatch will be atteched to ConsolidationRoot.
                //databaes Signal will be removed after consolidation finished.
                return(false);
            }

            //next consolidation batch should start after current batch is finished.
            //because need to prevent selecting extra items from previous batch and attach them twice to different consolidation batches.
            //repeat processing item later.
            _dispatchQueue.ApplyResult(item, ProcessingResult.Repeat);
            return(false);
        }
示例#3
0
        //methods
        public virtual bool Execute(SignalWrapper <SignalDispatch <TKey> > item)
        {
            //find Dispatcher by deliveryType
            IDispatchChannel <TKey> channel = _channelRegistry.Match(item.Signal);

            if (channel == null)
            {
                _dispatchQueue.ApplyResult(item, ProcessingResult.NoHandlerFound);
                return(false);
            }

            //send with dispatcher
            ProcessingResult sendResult = ProcessingResult.Fail;
            Stopwatch        sendTimer  = Stopwatch.StartNew();

            try
            {
                sendResult = channel.Send(item.Signal);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, null);
            }
            sendTimer.Stop();

            //check dispatcher availability
            DispatcherAvailability availability = CheckAvailability(channel, sendResult);

            if (sendResult == ProcessingResult.Fail && availability == DispatcherAvailability.NotAvailable)
            {
                sendResult = ProcessingResult.Repeat;
            }

            _monitor.DispatchSent(item.Signal, sendResult, sendTimer.Elapsed);
            channel.CountSendAttempt(item.Signal, sendResult, availability);
            _dispatchQueue.ApplyResult(item, sendResult);
            return(sendResult == ProcessingResult.Success);
        }
示例#4
0
 protected void ProcessSignal(SignalWrapper <SignalDispatch <TKey> > item)
 {
     try
     {
         foreach (IDispatchProcessingCommand <TKey> command in _processingCommands)
         {
             bool completed = command.Execute(item);
             if (!completed)
             {
                 break;
             }
         }
     }
     catch (Exception ex)
     {
         _logger.LogError(ex, null);
         _dispatchQueue.ApplyResult(item, ProcessingResult.Fail);
     }
 }