Skip to content

Commit

Permalink
Merge pull request #71 from IliyanIlievPH/master
Browse files Browse the repository at this point in the history
add try finally to release redis lock
  • Loading branch information
starkmsu committed Jun 18, 2020
2 parents a874476 + 10ad763 commit bd859d5
Showing 1 changed file with 127 additions and 119 deletions.
246 changes: 127 additions & 119 deletions src/MAVN.Service.SmartVouchers.DomainServices/VouchersService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,101 +122,106 @@ public async Task<VoucherReservationResult> ReserveVoucherAsync(Guid voucherCamp
continue;
}

var alreadyReservedVoucher = await _vouchersRepository.GetReservedVoucherForCustomerAsync(ownerId);
if (alreadyReservedVoucher != null)
return new VoucherReservationResult
try
{
var alreadyReservedVoucher = await _vouchersRepository.GetReservedVoucherForCustomerAsync(ownerId);
if (alreadyReservedVoucher != null)
{
ErrorCode = ProcessingVoucherError.CustomerHaveAnotherReservedVoucher,
AlreadyReservedVoucherShortCode = alreadyReservedVoucher.ShortCode
};
return new VoucherReservationResult
{
ErrorCode = ProcessingVoucherError.CustomerHaveAnotherReservedVoucher,
AlreadyReservedVoucherShortCode = alreadyReservedVoucher.ShortCode
};
}

var vouchers = await _vouchersRepository.GetByCampaignIdAndStatusAsync(voucherCampaignId, VoucherStatus.InStock);
Voucher voucher = null;
if (vouchers.Any())
{
try
var vouchers = await _vouchersRepository.GetByCampaignIdAndStatusAsync(voucherCampaignId, VoucherStatus.InStock);
Voucher voucher = null;
if (vouchers.Any())
{
voucher = vouchers.First();
if (voucherPriceIsZero)
try
{
voucher.Status = VoucherStatus.Sold;
voucher.OwnerId = ownerId;
voucher.PurchaseDate = DateTime.UtcNow;
await _vouchersRepository.UpdateAsync(voucher);
voucher = vouchers.First();
if (voucherPriceIsZero)
{
voucher.Status = VoucherStatus.Sold;
voucher.OwnerId = ownerId;
voucher.PurchaseDate = DateTime.UtcNow;
await _vouchersRepository.UpdateAsync(voucher);
}
else
{
await _vouchersRepository.ReserveAsync(voucher, ownerId);
}
}
else
catch (Exception e)
{
await _vouchersRepository.ReserveAsync(voucher, ownerId);
_log.Error(e);
return new VoucherReservationResult { ErrorCode = ProcessingVoucherError.NoAvailableVouchers };
}
}
catch (Exception e)
{
_log.Error(e);
await _redisLocksService.ReleaseLockAsync(voucherCampaignIdStr, ownerId.ToString());
return new VoucherReservationResult { ErrorCode = ProcessingVoucherError.NoAvailableVouchers };
}
}
else
{
var vouchersPage = await _vouchersRepository.GetByCampaignIdAsync(voucherCampaignId, 0, 1);
if (vouchersPage.TotalCount >= campaign.VouchersTotalCount)
{
await _redisLocksService.ReleaseLockAsync(voucherCampaignIdStr, ownerId.ToString());
return new VoucherReservationResult { ErrorCode = ProcessingVoucherError.NoAvailableVouchers };
}

var validationCode = GenerateValidation();
voucher = new Voucher
else
{
CampaignId = voucherCampaignId,
Status = voucherPriceIsZero ? VoucherStatus.Sold : VoucherStatus.Reserved,
OwnerId = ownerId,
PurchaseDate = DateTime.UtcNow,
};
var vouchersPage = await _vouchersRepository.GetByCampaignIdAsync(voucherCampaignId, 0, 1);
if (vouchersPage.TotalCount >= campaign.VouchersTotalCount)
{
return new VoucherReservationResult { ErrorCode = ProcessingVoucherError.NoAvailableVouchers };
}

voucher.Id = await _vouchersRepository.CreateAsync(voucher);
voucher.ShortCode = GenerateShortCodeFromId(voucher.Id);
var validationCode = GenerateValidation();
voucher = new Voucher
{
CampaignId = voucherCampaignId,
Status = voucherPriceIsZero ? VoucherStatus.Sold : VoucherStatus.Reserved,
OwnerId = ownerId,
PurchaseDate = DateTime.UtcNow,
};

await _vouchersRepository.UpdateAsync(voucher, validationCode);
}
voucher.Id = await _vouchersRepository.CreateAsync(voucher);
voucher.ShortCode = GenerateShortCodeFromId(voucher.Id);

await _redisLocksService.ReleaseLockAsync(voucherCampaignIdStr, ownerId.ToString());
await _vouchersRepository.UpdateAsync(voucher, validationCode);
}

if (voucherPriceIsZero)
{
await PublishVoucherSoldEvent(null, campaign, voucher);
return new VoucherReservationResult
if (voucherPriceIsZero)
{
ErrorCode = ProcessingVoucherError.None
};
}
await PublishVoucherSoldEvent(null, campaign, voucher);
return new VoucherReservationResult
{
ErrorCode = ProcessingVoucherError.None
};
}

var paymentRequestResult = await _paymentManagementClient.Api.GeneratePaymentAsync(
new PaymentGenerationRequest
var paymentRequestResult = await _paymentManagementClient.Api.GeneratePaymentAsync(
new PaymentGenerationRequest
{
CustomerId = ownerId,
Amount = campaign.VoucherPrice,
Currency = campaign.Currency,
PartnerId = campaign.PartnerId,
ExternalPaymentEntityId = voucher.ShortCode,
});

if (paymentRequestResult.ErrorCode != PaymentGenerationErrorCode.None)
{
CustomerId = ownerId,
Amount = campaign.VoucherPrice,
Currency = campaign.Currency,
PartnerId = campaign.PartnerId,
ExternalPaymentEntityId = voucher.ShortCode,
});
await CancelReservationAsync(voucher.ShortCode);
return new VoucherReservationResult
{
ErrorCode = ProcessingVoucherError.InvalidPartnerPaymentConfiguration,
};
}

await _paymentRequestsRepository.CreatePaymentRequestAsync(paymentRequestResult.PaymentRequestId, voucher.ShortCode);

if (paymentRequestResult.ErrorCode != PaymentGenerationErrorCode.None)
{
await CancelReservationAsync(voucher.ShortCode);
return new VoucherReservationResult
{
ErrorCode = ProcessingVoucherError.InvalidPartnerPaymentConfiguration,
ErrorCode = ProcessingVoucherError.None,
PaymentUrl = paymentRequestResult.PaymentPageUrl,
};
}

await _paymentRequestsRepository.CreatePaymentRequestAsync(paymentRequestResult.PaymentRequestId, voucher.ShortCode);

return new VoucherReservationResult
finally
{
ErrorCode = ProcessingVoucherError.None,
PaymentUrl = paymentRequestResult.PaymentPageUrl,
};
await _redisLocksService.ReleaseLockAsync(voucherCampaignIdStr, ownerId.ToString());
}
}

_log.Warning($"Couldn't get a lock for voucher campaign {voucherCampaignId}");
Expand Down Expand Up @@ -257,64 +262,67 @@ public async Task<PresentVouchersResult> PresentVouchersAsync(Guid campaignId, G
continue;
}

var reservedVouchersCount = await _vouchersRepository.GetReservedVouchersCountForCampaign(campaignId);
var availableVouchersCount = campaign.VouchersTotalCount - campaign.BoughtVouchersCount - reservedVouchersCount;
if (availableVouchersCount < customerIds.Count)
try
{
await _redisLocksService.ReleaseLockAsync(voucherCampaignIdStr, adminIdStr);
return new PresentVouchersResult { Error = PresentVouchersErrorCodes.NotEnoughVouchersInStock };
}
var reservedVouchersCount = await _vouchersRepository.GetReservedVouchersCountForCampaign(campaignId);
var availableVouchersCount = campaign.VouchersTotalCount - campaign.BoughtVouchersCount - reservedVouchersCount;

var vouchers = await _vouchersRepository.GetByCampaignIdAndStatusAsync(campaignId, VoucherStatus.InStock);
foreach (var customerId in customerIds)
{
Voucher voucher = null;
if (vouchers.Any())
{
voucher = vouchers.First();
if (availableVouchersCount < customerIds.Count)
return new PresentVouchersResult { Error = PresentVouchersErrorCodes.NotEnoughVouchersInStock };

voucher.Status = VoucherStatus.Sold;
voucher.OwnerId = customerId;
voucher.PurchaseDate = DateTime.UtcNow;
await _vouchersRepository.UpdateAsync(voucher);
vouchers.Remove(voucher);
}
else
var vouchers = await _vouchersRepository.GetByCampaignIdAndStatusAsync(campaignId, VoucherStatus.InStock);
foreach (var customerId in customerIds)
{
var validationCode = GenerateValidation();
voucher = new Voucher
Voucher voucher = null;
if (vouchers.Any())
{
CampaignId = campaignId,
Status = VoucherStatus.Sold,
OwnerId = customerId,
PurchaseDate = DateTime.UtcNow,
};
voucher = vouchers.First();

voucher.Id = await _vouchersRepository.CreateAsync(voucher);
voucher.ShortCode = GenerateShortCodeFromId(voucher.Id);
voucher.Status = VoucherStatus.Sold;
voucher.OwnerId = customerId;
voucher.PurchaseDate = DateTime.UtcNow;
await _vouchersRepository.UpdateAsync(voucher);
vouchers.Remove(voucher);
}
else
{
var validationCode = GenerateValidation();
voucher = new Voucher
{
CampaignId = campaignId,
Status = VoucherStatus.Sold,
OwnerId = customerId,
PurchaseDate = DateTime.UtcNow,
};

voucher.Id = await _vouchersRepository.CreateAsync(voucher);
voucher.ShortCode = GenerateShortCodeFromId(voucher.Id);

await _vouchersRepository.UpdateAsync(voucher, validationCode);
}

await _vouchersRepository.UpdateAsync(voucher, validationCode);
await _voucherSoldPublisher.PublishAsync(new SmartVoucherSoldEvent
{
CampaignId = campaignId,
PartnerId = campaign.PartnerId,
Amount = 0,
Currency = campaign.Currency,
CustomerId = customerId,
Timestamp = DateTime.UtcNow,
VoucherShortCode = voucher.ShortCode,
});
}

await _voucherSoldPublisher.PublishAsync(new SmartVoucherSoldEvent
return new PresentVouchersResult
{
CampaignId = campaignId,
PartnerId = campaign.PartnerId,
Amount = 0,
Currency = campaign.Currency,
CustomerId = customerId,
Timestamp = DateTime.UtcNow,
VoucherShortCode = voucher.ShortCode,
});
Error = PresentVouchersErrorCodes.None,
NotRegisteredEmails = notRegisteredEmails.ToList(),
};
}

await _redisLocksService.ReleaseLockAsync(voucherCampaignIdStr, adminIdStr);

return new PresentVouchersResult
finally
{
Error = PresentVouchersErrorCodes.None,
NotRegisteredEmails = notRegisteredEmails.ToList(),
};
await _redisLocksService.ReleaseLockAsync(voucherCampaignIdStr, adminIdStr);
}
}

_log.Warning($"Couldn't get a lock when trying to present vouchers for voucher campaign {campaign}");
Expand Down

0 comments on commit bd859d5

Please sign in to comment.