public override async Task <Empty> ReleaseLock(Lock request, ServerCallContext context) { var currentLock = await _expiringDataStore.Get <Lock>(request.ResourceId); if (currentLock.IsNullOrDefault()) { throw new RpcException(new Status(StatusCode.NotFound, $"No lock found for resource: {request.ResourceId}"), $"No lock found for resource: {request.ResourceId}"); } if (!currentLock.LockId.Equals(request.LockId, StringComparison.OrdinalIgnoreCase)) { throw new RpcException(new Status(StatusCode.Unavailable, $"Unable to release lock, the lockId: {request.LockId} is incorrect."), $"Unable to release lock, the lockId: {request.LockId} is incorrect."); } if (!await _lockProvider.ReleaseLock(new LockToken(true, currentLock.LockId, currentLock.ResourceId, currentLock.Expiry.ToDateTime()))) { throw new RpcException(new Status(StatusCode.Unavailable, "Unable to release lock."), "Unable to release lock."); } await _expiringDataStore.Delete <Lock>(currentLock.ResourceId); currentLock.Expiry = DateTime.UtcNow.AddSeconds(5).ToTimestamp(); currentLock.Released = false; await _producer.ProduceAsync(currentLock, request.ResourceId); return(new Empty()); }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) => await _dataStore.ExpiredKeys .Retry() .Select(k => k.Split("/")) .Where(k => k[0].Equals("locks")) .ForEachAsync(async expiredLock => { var lockKey = expiredLock[1]; var lockValue = await _dataStore.Get <Lock>(lockKey); if (!lockValue.IsNotNullOrDefault()) { return; } await _lockProducer.ProduceAsync(lockValue, lockValue.ResourceId); await _dataStore.Delete <Lock>(lockKey); Console.WriteLine($"Expired {lockKey}."); }, stoppingToken);