diff --git a/QRBee.Load.Generator/AnomalyBase.cs b/QRBee.Load.Generator/AnomalyBase.cs index ae4c257..5e6221c 100644 --- a/QRBee.Load.Generator/AnomalyBase.cs +++ b/QRBee.Load.Generator/AnomalyBase.cs @@ -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) { - _anomalyStart = DateTime.Now; + 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; diff --git a/QRBee.Load.Generator/UnconfirmedTransactions.cs b/QRBee.Load.Generator/UnconfirmedTransactions.cs index f475fc5..2fc5956 100644 --- a/QRBee.Load.Generator/UnconfirmedTransactions.cs +++ b/QRBee.Load.Generator/UnconfirmedTransactions.cs @@ -10,5 +10,5 @@ internal class UnconfirmedTransactions : AnomalyBase { } - public bool ShouldConfirm() => IsActive(); + public bool ShouldConfirm() => !IsActive(); } diff --git a/QRBee/QRBee.Android/Resources/Resource.designer.cs b/QRBee/QRBee.Android/Resources/Resource.designer.cs index 89e6ccb..d8d02ea 100644 --- a/QRBee/QRBee.Android/Resources/Resource.designer.cs +++ b/QRBee/QRBee.Android/Resources/Resource.designer.cs @@ -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 { diff --git a/QRBeeApi/Services/CustomMetrics.cs b/QRBeeApi/Services/CustomMetrics.cs index 0f6dbe2..bbcf893 100644 --- a/QRBeeApi/Services/CustomMetrics.cs +++ b/QRBeeApi/Services/CustomMetrics.cs @@ -10,6 +10,7 @@ namespace QRBee.Api.Services private Counter FailedTransactionsCounter { get; } private Counter CorruptTransactionsCounter { get; } private Counter CancelledTransactionsCounter { get; } + private Counter FailedTransactionsCancellationCounter { get; } private Counter SucceededPaymentConfirmationsCounter { get; } private Counter FailedPaymentConfirmationsCounter { get; } private Counter TotalCreditCardCheckTime { get; } @@ -24,16 +25,17 @@ namespace QRBee.Api.Services var meter = new Meter(meterName); MetricName = meterName; - MerchantRequestCounter = meter.CreateCounter("merchant-requests", description: "Merchant has sent a request"); + MerchantRequestCounter = meter.CreateCounter("merchant-requests", description: "Merchant has sent a request"); MerchantResponseCounter = meter.CreateCounter("merchant-responses"); - SucceededTransactionsCounter = meter.CreateCounter("transaction-succeeded", description: "Transaction succeeded"); - FailedTransactionsCounter = meter.CreateCounter("transaction-failed", description: "Transaction failed"); - CorruptTransactionsCounter = meter.CreateCounter("transaction-corrupt", description: "Transaction was corrupted"); - CancelledTransactionsCounter = meter.CreateCounter("transaction-cancelled", description: "Transaction was cancelled by TransactionMonitoring class"); + SucceededTransactionsCounter = meter.CreateCounter("transaction-succeeded", description: "Transaction succeeded"); + FailedTransactionsCounter = meter.CreateCounter("transaction-failed", description: "Transaction failed"); + CorruptTransactionsCounter = meter.CreateCounter("transaction-corrupt", description: "Transaction was corrupted"); + CancelledTransactionsCounter = meter.CreateCounter("transaction-cancelled", description: "Transaction was cancelled due to cancellation timeout"); + FailedTransactionsCancellationCounter= meter.CreateCounter("transaction-cancellation-failed", description: "Transaction was not cancelled due to payment gateway failure"); - SucceededPaymentConfirmationsCounter = meter.CreateCounter("payment-confirmation-succeeded", description: "Payment confirmation succeeded"); - FailedPaymentConfirmationsCounter = meter.CreateCounter("payment-confirmation-failed", description: "Payment confirmation failed"); + SucceededPaymentConfirmationsCounter = meter.CreateCounter("payment-confirmation-succeeded", description: "Payment confirmation succeeded"); + FailedPaymentConfirmationsCounter = meter.CreateCounter("payment-confirmation-failed", description: "Payment confirmation failed"); TotalCreditCardCheckTime = meter.CreateCounter("total-credit-card-check-time","msec"); TotalPaymentTime = meter.CreateCounter("total-payment-time","msec"); @@ -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); diff --git a/QRBeeApi/Services/PaymentGateway.cs b/QRBeeApi/Services/PaymentGateway.cs index 5ccb316..f0034e4 100644 --- a/QRBeeApi/Services/PaymentGateway.cs +++ b/QRBeeApi/Services/PaymentGateway.cs @@ -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, diff --git a/QRBeeApi/Services/TransactionMonitoring.cs b/QRBeeApi/Services/TransactionMonitoring.cs index 08f8861..574a4ee 100644 --- a/QRBeeApi/Services/TransactionMonitoring.cs +++ b/QRBeeApi/Services/TransactionMonitoring.cs @@ -7,8 +7,9 @@ namespace QRBee.Api.Services private readonly IStorage _storage; private readonly IPaymentGateway _paymentGateway; private readonly ILogger _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(); } } }