Esempio n. 1
0
        //flush complete handlers
        protected virtual void ForgetDispatchLocks(List <SignalWrapper <SignalDispatch <TKey> > > flushedItems)
        {
            var ids = flushedItems.Select(x => x.Signal.SignalDispatchId);

            _dispatchLockTracker.ForgetLocks(ids);

            ids = flushedItems
                  .Where(x => x.ConsolidatedSignals != null)
                  .SelectMany(x => x.ConsolidatedSignals)
                  .Select(x => x.Signal.SignalDispatchId);
            _dispatchLockTracker.ForgetLocks(ids);
        }
        //methods
        public bool Execute(SignalWrapper <SignalDispatch <TKey> > item)
        {
            bool isLockingEnabled = _settings.IsDbLockStorageEnabled;

            if (!isLockingEnabled)
            {
                return(true);
            }

            if (item.Signal.ShouldBeConsolidated())
            {
                //consolidated items have their own locks for the whole consolidated group of dispatches
                return(true);
            }

            bool isLockExpired = _lockTracker.CheckNeedToExtendLock(item.Signal.SignalDispatchId);

            if (!isLockExpired)
            {
                return(true);
            }

            //Lock again before sending
            DateTime lockExpirationDate = _lockTracker.GetMaxExpiredLockSinceUtc();
            bool     lockSet            = _dispatchQueries.SetLock(new List <TKey> {
                item.Signal.SignalDispatchId
            },
                                                                   lockId: _settings.LockedByInstanceId.Value,
                                                                   newLockSinceTimeUtc: DateTime.UtcNow,
                                                                   existingLockSinceDateUtc: lockExpirationDate)
                                          .Result;

            if (lockSet)
            {
                return(true);
            }

            //If already expired and locked by another Sender instance, do nothing and let another instance to process.
            _lockTracker.ForgetLocks(new List <TKey> {
                item.Signal.SignalDispatchId
            });

            //cancel any future steps
            return(false);
        }