public Task <DedupeClaim> GetLease(string messageId)
    {
        var now    = DateTime.UtcNow;
        var entity = new DedupeClaimImp
        {
            MessageId       = messageId,
            LeaseExpiration = now.Add(LeaseDuration),
            Revision        = 1,
            Timestamp       = now
        };

        if (Items.TryAdd(messageId, entity))
        {
            return(Task.FromResult <DedupeClaim>(entity));
        }

        var previous = entity = Items[messageId];

        if (entity.IsProcessed)
        {
            return(Task.FromResult <DedupeClaim>(entity));
        }

        var isLeaseExpired = entity.LeaseExpiration < now;

        if (!isLeaseExpired)
        {
            throw new Exception($"Lease not expired for {messageId}.");
        }

        entity.LeaseExpiration = now + LeaseDuration;

        if (!Items.TryUpdate(messageId, entity, previous))
        {
            throw new Exception($"Lease for {messageId} taken by other incoming message.");
        }

        return(Task.FromResult <DedupeClaim>(entity));
    }
 public bool Equals(DedupeClaimImp other)
 {
     return(string.Equals(MessageId, other.MessageId) && Revision == other.Revision);
 }