public bool CheckStatus(string updaterUniqueId, int pollingValue) { var lastUpdate = _orderStatusUpdateDao.GetLastUpdate(); bool hasOrdersWaitingForPayment = false; Log.DebugFormat("Attempting to CheckStatus with {0}", updaterUniqueId); if ((lastUpdate == null) || (lastUpdate.UpdaterUniqueId == updaterUniqueId) || (DateTime.UtcNow.Subtract(lastUpdate.LastUpdateDate).TotalSeconds > NumberOfConcurrentServers * pollingValue)) { var cycleStartDateTime = DateTime.UtcNow; // Update LastUpdateDate while processing to block the other instance from starting while we're executing the try block var timer = Observable.Timer(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(pollingValue)) .Subscribe(_ => _orderStatusUpdateDao.UpdateLastUpdate(updaterUniqueId, DateTime.UtcNow, cycleStartDateTime)); Log.DebugFormat("CheckStatus was allowed for {0}", updaterUniqueId); try { // keep the old status job like it was before var orders = _orderDao.GetOrdersInProgress(false); orders = orders.Concat(_orderDao.GetOrdersInProgress(true)).ToList(); var groupedOrders = orders.GroupBy(x => new { x.CompanyKey, x.Market }); foreach (var orderGroup in groupedOrders) { var ordersForCompany = orderGroup.ToArray(); Log.DebugFormat("Starting BatchUpdateStatus with {0} orders{1}", ordersForCompany.Count(), string.IsNullOrWhiteSpace(orderGroup.Key.CompanyKey) ? string.Empty : string.Format(" for company {0}", orderGroup.Key.CompanyKey)); Log.DebugFormat("Starting BatchUpdateStatus with {0} orders of status {1}", ordersForCompany.Count(o => o.Status == OrderStatus.WaitingForPayment), "WaitingForPayment"); BatchUpdateStatus(orderGroup.Key.CompanyKey, orderGroup.Key.Market, ordersForCompany.Where(o => o.Status == OrderStatus.WaitingForPayment)); Log.DebugFormat("Starting BatchUpdateStatus with {0} orders of status {1}", ordersForCompany.Count(o => o.Status == OrderStatus.Pending), "Pending"); BatchUpdateStatus(orderGroup.Key.CompanyKey, orderGroup.Key.Market, ordersForCompany.Where(o => o.Status == OrderStatus.Pending)); Log.DebugFormat("Starting BatchUpdateStatus with {0} orders of status {1}", ordersForCompany.Count(o => o.Status == OrderStatus.TimedOut), "TimedOut"); BatchUpdateStatus(orderGroup.Key.CompanyKey, orderGroup.Key.Market, ordersForCompany.Where(o => o.Status == OrderStatus.TimedOut)); Log.DebugFormat("Starting BatchUpdateStatus with {0} orders of status {1}", ordersForCompany.Count(o => o.Status == OrderStatus.Created), "Created"); BatchUpdateStatus(orderGroup.Key.CompanyKey, orderGroup.Key.Market, ordersForCompany.Where(o => o.Status == OrderStatus.Created)); } hasOrdersWaitingForPayment = orders.Any(o => o.Status == OrderStatus.WaitingForPayment); } finally { timer.Dispose(); } } else { Log.DebugFormat("CheckStatus was blocked for {0}", updaterUniqueId); } return(hasOrdersWaitingForPayment); }
public bool CheckStatus(string uniqueId, int pollingValue) { Log.WarnFormat("FAKE IBS ACTIVE. only manual RideLinq orders will be processed"); var lastUpdate = _orderStatusUpdateDao.GetLastUpdate(); if (lastUpdate != null && lastUpdate.UpdaterUniqueId != uniqueId && !(DateTime.UtcNow.Subtract(lastUpdate.LastUpdateDate).TotalSeconds > NumberOfConcurrentServers * pollingValue)) { return(false); } var cycleStartDateTime = DateTime.UtcNow; // Update LastUpdateDate while processing to block the other instance from starting while we're executing the try block var timer = Observable.Timer(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(pollingValue)) .Subscribe(_ => _orderStatusUpdateDao.UpdateLastUpdate(uniqueId, DateTime.UtcNow, cycleStartDateTime)); try { var orders = _orderDao.GetOrdersInProgress(true) .Where(x => x.Status == OrderStatus.Created); foreach (var orderStatusDetail in orders) { Log.InfoFormat("Starting OrderStatusUpdater for order {0} (Paired via Manual RideLinQ code).", orderStatusDetail.OrderId); _orderStatusUpdater.HandleManualRidelinqFlow(orderStatusDetail); } } finally { timer.Dispose(); } // No op return(false); }
public bool CheckStatus(string updaterUniqueId, int pollingValue) { var lastUpdate = _orderStatusUpdateDao.GetLastUpdate(); var hasOrdersWaitingForPayment = false; Log.DebugFormat("Attempting to CheckStatus with {0}", updaterUniqueId); if ((lastUpdate == null) || (lastUpdate.UpdaterUniqueId == updaterUniqueId) || (DateTime.UtcNow.Subtract(lastUpdate.LastUpdateDate).TotalSeconds > NumberOfConcurrentServers * pollingValue)) { var cycleStartDateTime = DateTime.UtcNow; // Update LastUpdateDate while processing to block the other instance from starting while we're executing the try block var timer = Observable.Timer(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(pollingValue)) .Subscribe(_ => _orderStatusUpdateDao.UpdateLastUpdate(updaterUniqueId, DateTime.UtcNow, cycleStartDateTime)); // If this timer elapses, it will dispose the first timer which would allow another process to start var deadlockTimer = Observable.Timer(TimeSpan.FromMinutes(15)) .Subscribe(_ => { timer.Dispose(); Log.FatalFormat("Deadlock Timer has elapsed on {0}\n" + "LastUpdate timer will now stop and allow another process to continue processing orders.\n" + "This could mean OrderStatusUpdater has encountered an unhandled error that should be investigated ASAP." + "The website should be able to recover because an attempt to restart it has been made.", updaterUniqueId); HttpRuntime.UnloadAppDomain(); }); Log.DebugFormat("CheckStatus was allowed for {0}", updaterUniqueId); try { // Normal IBS handling var orders = _orderDao.GetOrdersInProgress(false); var groupedOrders = orders.GroupBy(x => new { x.CompanyKey, x.Market }); foreach (var orderGroup in groupedOrders) { var ordersForCompany = orderGroup.ToArray(); Log.DebugFormat("Starting BatchUpdateStatusForIbs with {0} orders{1}", ordersForCompany.Count(), string.IsNullOrWhiteSpace(orderGroup.Key.CompanyKey) ? string.Empty : string.Format(" for company {0}", orderGroup.Key.CompanyKey)); Log.DebugFormat("Starting BatchUpdateStatusForIbs with {0} orders of status {1}", ordersForCompany.Count(o => o.Status == OrderStatus.WaitingForPayment), "WaitingForPayment"); BatchUpdateStatusForIbs(orderGroup.Key.CompanyKey, orderGroup.Key.Market, ordersForCompany.Where(o => o.Status == OrderStatus.WaitingForPayment)); Log.DebugFormat("Starting BatchUpdateStatusForIbs with {0} orders of status {1}", ordersForCompany.Count(o => o.Status == OrderStatus.Pending), "Pending"); BatchUpdateStatusForIbs(orderGroup.Key.CompanyKey, orderGroup.Key.Market, ordersForCompany.Where(o => o.Status == OrderStatus.Pending)); Log.DebugFormat("Starting BatchUpdateStatusForIbs with {0} orders of status {1}", ordersForCompany.Count(o => o.Status == OrderStatus.TimedOut), "TimedOut"); BatchUpdateStatusForIbs(orderGroup.Key.CompanyKey, orderGroup.Key.Market, ordersForCompany.Where(o => o.Status == OrderStatus.TimedOut)); Log.DebugFormat("Starting BatchUpdateStatusForIbs with {0} orders of status {1}", ordersForCompany.Count(o => o.Status == OrderStatus.Created), "Created"); BatchUpdateStatusForIbs(orderGroup.Key.CompanyKey, orderGroup.Key.Market, ordersForCompany.Where(o => o.Status == OrderStatus.Created)); } hasOrdersWaitingForPayment = orders.Any(o => o.Status == OrderStatus.WaitingForPayment); // Manual RideLinq handling var manualRideLinqOrders = _orderDao.GetOrdersInProgress(true); Log.DebugFormat("Starting BatchUpdateStatusForManualRideLinq with {0} orders ({1} waiting for payment)", manualRideLinqOrders.Count, manualRideLinqOrders.Count(x => x.Status == OrderStatus.WaitingForPayment)); BatchUpdateStatusForManualRideLinq(manualRideLinqOrders); } finally { deadlockTimer.Dispose(); timer.Dispose(); // Needed to ensure we do not have a false positive in deadlock detection. _orderStatusUpdateDao.UpdateLastUpdate(updaterUniqueId, DateTime.UtcNow, null); Log.DebugFormat("CheckStatus completed for {0}", updaterUniqueId); } } else { Log.DebugFormat("CheckStatus was blocked for {0} by {1}", updaterUniqueId, lastUpdate.UpdaterUniqueId); } return(hasOrdersWaitingForPayment); }