public async Task <bool> Handle(T message)
        {
            string lockKey = $"{message.UniqueKey()}-{_lockSuffixKeyForHandler}";
            MessageLockResponse lockResponse = await _messageLock.TryAquireLockAsync(lockKey, _timeout).ConfigureAwait(false);

            if (!lockResponse.DoIHaveExclusiveLock)
            {
                if (lockResponse.IsMessagePermanentlyLocked)
                {
                    return(RemoveTheMessageFromTheQueue);
                }

                return(LeaveItInTheQueue);
            }

            try
            {
                bool successfullyHandled = await _inner.Handle(message).ConfigureAwait(false);

                if (successfullyHandled)
                {
                    await _messageLock.TryAquireLockPermanentlyAsync(lockKey).ConfigureAwait(false);
                }

                return(successfullyHandled);
            }
            catch (Exception)
            {
                await _messageLock.ReleaseLockAsync(lockKey).ConfigureAwait(false);

                throw;
            }
        }
        protected override void Given()
        {
            base.Given();

            var messageLockResponse = new MessageLockResponse
            {
                DoIHaveExclusiveLock = true
            };

            MessageLock = Substitute.For<IMessageLock>();
            MessageLock.TryAquireLock(Arg.Any<string>(), Arg.Any<TimeSpan>())
                .Returns(messageLockResponse);

            _handler = new ExactlyOnceSignallingHandler(_tcs);
            Handler = _handler;
        }
        public async Task <bool> Handle(T message)
        {
            string lockKey = $"{message.UniqueKey()}-{_lockSuffixKeyForHandler}";
            MessageLockResponse lockResponse = await _messageLock.TryAquireLockAsync(lockKey, _timeout).ConfigureAwait(false);

            if (!lockResponse.DoIHaveExclusiveLock)
            {
                if (lockResponse.IsMessagePermanentlyLocked)
                {
                    _logger.LogDebug("Failed to acquire lock for message with key {MessageLockKey} as it is permanently locked.", lockKey);
                    return(RemoveTheMessageFromTheQueue);
                }

                _logger.LogDebug("Failed to acquire lock for message with key {MessageLockKey}; returning message to queue.", lockKey);
                return(LeaveItInTheQueue);
            }

            try
            {
                _logger.LogDebug("Acquired lock for message with key {MessageLockKey}.", lockKey);

                bool successfullyHandled = await _inner.Handle(message).ConfigureAwait(false);

                if (successfullyHandled)
                {
                    await _messageLock.TryAquireLockPermanentlyAsync(lockKey).ConfigureAwait(false);

                    _logger.LogDebug("Acquired permanent lock for message with key {MessageLockKey}.", lockKey);
                }

                return(successfullyHandled);
            }
            catch (Exception)
            {
                await _messageLock.ReleaseLockAsync(lockKey).ConfigureAwait(false);

                _logger.LogDebug("Released lock for message with key {MessageLockKey}.", lockKey);
                throw;
            }
        }