DEEP-42 FailedTransaction confirmation counter added. Fixed unconfirmed transactions anomaly

This commit is contained in:
Andrey Shabarshov 2023-08-19 10:12:29 +01:00
parent 263f132a22
commit 805448cd72
6 changed files with 45 additions and 19 deletions

View File

@ -14,6 +14,11 @@ internal class AnomalyBase
private TimeSpan _anomalyDuration;
private readonly object _lock = new();
public static bool OneAtATime { get; set; } = true;
protected static bool OneIsActive = false;
protected static readonly object _globalLock = new();
public string Name { get; }
public AnomalyBase(string name, Anomaly settings, ILogger logger, IAnomalyReporter anomalyReporter)
@ -46,6 +51,12 @@ internal class AnomalyBase
_anomalyActive = false;
_anomalyReporter.Report(_anomalyStart, _anomalyEnd, Name);
_logger.LogWarning($"Anomaly:{Name} ended");
lock(_globalLock)
{
if ( OneAtATime )
OneIsActive = false;
}
}
}
}
@ -57,11 +68,18 @@ internal class AnomalyBase
{
if (!_anomalyActive)
{
lock (_globalLock)
{
if (OneAtATime && OneIsActive)
return false;
if (OneAtATime)
OneIsActive = true;
}
_anomalyStart = DateTime.Now;
_anomalyEnd = _anomalyStart + _anomalyDuration;
_anomalyActive = true;
_logger.LogWarning($"Anomaly: {Name}. Dice={dice} Ends=\"{_anomalyEnd.ToLocalTime():s}\"");
//_anomalyReporter.Report(_anomalyStart, _anomalyEnd, $"{Name}");
}
}
return true;

View File

@ -10,5 +10,5 @@ internal class UnconfirmedTransactions : AnomalyBase
{
}
public bool ShouldConfirm() => IsActive();
public bool ShouldConfirm() => !IsActive();
}

View File

@ -14,7 +14,7 @@ namespace QRBee.Droid
{
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "13.2.0.99")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "13.2.1.111")]
public partial class Resource
{

View File

@ -10,6 +10,7 @@ namespace QRBee.Api.Services
private Counter<int> FailedTransactionsCounter { get; }
private Counter<int> CorruptTransactionsCounter { get; }
private Counter<int> CancelledTransactionsCounter { get; }
private Counter<int> FailedTransactionsCancellationCounter { get; }
private Counter<int> SucceededPaymentConfirmationsCounter { get; }
private Counter<int> FailedPaymentConfirmationsCounter { get; }
private Counter<long> TotalCreditCardCheckTime { get; }
@ -30,7 +31,8 @@ namespace QRBee.Api.Services
SucceededTransactionsCounter = meter.CreateCounter<int>("transaction-succeeded", description: "Transaction succeeded");
FailedTransactionsCounter = meter.CreateCounter<int>("transaction-failed", description: "Transaction failed");
CorruptTransactionsCounter = meter.CreateCounter<int>("transaction-corrupt", description: "Transaction was corrupted");
CancelledTransactionsCounter = meter.CreateCounter<int>("transaction-cancelled", description: "Transaction was cancelled by TransactionMonitoring class");
CancelledTransactionsCounter = meter.CreateCounter<int>("transaction-cancelled", description: "Transaction was cancelled due to cancellation timeout");
FailedTransactionsCancellationCounter= meter.CreateCounter<int>("transaction-cancellation-failed", description: "Transaction was not cancelled due to payment gateway failure");
SucceededPaymentConfirmationsCounter = meter.CreateCounter<int>("payment-confirmation-succeeded", description: "Payment confirmation succeeded");
FailedPaymentConfirmationsCounter = meter.CreateCounter<int>("payment-confirmation-failed", description: "Payment confirmation failed");
@ -50,6 +52,7 @@ namespace QRBee.Api.Services
public void AddFailedTransaction() => FailedTransactionsCounter.Add(1);
public void AddCorruptTransaction() => CorruptTransactionsCounter.Add(1);
public void AddCancelledTransaction() => CancelledTransactionsCounter.Add(1);
public void AddFailedTransactionCancellation() => FailedTransactionsCancellationCounter.Add(1);
public void AddSucceededPaymentConfirmation() => SucceededPaymentConfirmationsCounter.Add(1);
public void AddFailedPaymentConfirmation() => FailedPaymentConfirmationsCounter.Add(1);
public void AddTotalCreditCardCheckTime(long milliseconds) => TotalCreditCardCheckTime.Add(milliseconds);

View File

@ -36,16 +36,17 @@ internal class PaymentGateway : IPaymentGateway
{
if (!string.IsNullOrWhiteSpace(info.GatewayTransactionId))
{
_logger.LogInformation($"Transaction with id: {info.Id} was cancelled");
var m = "Either payment gateway isn't working or the transaction is old";
_logger.LogError($"Transaction with id: {info.Id} was not cancelled: {m}");
return Task.FromResult(new GatewayResponse
{
Success = false,
ErrorMessage = "Either payment gateway isn't working or the transaction is old",
ErrorMessage = m,
GatewayTransactionId = info.GatewayTransactionId
});
}
_logger.LogInformation($"Transaction with id: {info.Id} succeeded");
_logger.LogInformation($"Transaction with id: {info.Id} was cancelled");
return Task.FromResult(new GatewayResponse
{
Success = true,

View File

@ -7,8 +7,9 @@ namespace QRBee.Api.Services
private readonly IStorage _storage;
private readonly IPaymentGateway _paymentGateway;
private readonly ILogger<TransactionMonitoring> _logger;
private const double Minutes = 2;
private const double Seconds = 30;
private const double TransactionInactivityMinutes = 1;
private const double LoopIntervalSeconds = 5;
private static bool _started;
private static object _syncObject = new();
@ -41,7 +42,7 @@ namespace QRBee.Api.Services
while (true)
{
await CheckTransactions();
await Task.Delay(TimeSpan.FromSeconds(Seconds));
await Task.Delay(TimeSpan.FromSeconds(LoopIntervalSeconds));
}
}
@ -52,7 +53,7 @@ namespace QRBee.Api.Services
foreach (var transaction in list)
{
if (transaction.ServerTimeStamp + TimeSpan.FromMinutes(Minutes) > DateTime.UtcNow)
if (transaction.ServerTimeStamp + TimeSpan.FromMinutes(TransactionInactivityMinutes) > DateTime.UtcNow)
{
// _logger.LogDebug($"Transaction: {transaction.MerchantTransactionId} should not be cancelled yet (ServerTimeStamp: {transaction.ServerTimeStamp:O}, Now: {DateTime.UtcNow:O})");
continue;
@ -75,12 +76,15 @@ namespace QRBee.Api.Services
_logger.LogError(e, $"Transaction: {transaction.MerchantTransactionId} can't be cancelled: {e.Message}");
transaction.Status = TransactionInfo.TransactionStatus.CancelFailed;
await _storage.UpdateTransaction(transaction);
_customMetrics.AddFailedTransactionCancellation();
return;
}
transaction.Status = TransactionInfo.TransactionStatus.Cancelled;
_customMetrics.AddCancelledTransaction();
await _storage.UpdateTransaction(transaction);
_customMetrics.AddCancelledTransaction();
}
}
}