Ejemplo n.º 1
0
        /// <summary>
        /// Simple routine for failing a work queue item.
        /// </summary>
        /// <param name="item">The item to fail.</param>
        /// <param name="failureDescription">The reason for the failure.</param>
        protected virtual void FailQueueItem(Model.WorkQueue item, string failureDescription)
        {
            int retryCount = 0;
            while (true)
            {
                try
                {
            DBUpdateTime.Add(
                delegate
                    {
                            #region Remove the WorkQueue entry
                        using (IUpdateContext updateContext = PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush))
                        {
                            IUpdateWorkQueue update = updateContext.GetBroker<IUpdateWorkQueue>();
                            UpdateWorkQueueParameters parms = new UpdateWorkQueueParameters
                                                                  {
                                                                      ProcessorID = ServerPlatform.ProcessorId,
                                                                      WorkQueueKey = item.GetKey(),
                                                                      StudyStorageKey = item.StudyStorageKey,
                                                                      FailureCount = item.FailureCount + 1,
                                                                      FailureDescription = failureDescription
                                                                  };

                            var settings = WorkQueueSettings.Instance;
                            if ((item.FailureCount + 1) > WorkQueueProperties.MaxFailureCount)
                            {
                                Platform.Log(LogLevel.Error,
                                             "Failing {0} WorkQueue entry ({1}), reached max retry count of {2}. Failure Reason: {3}",
                                                 item.WorkQueueTypeEnum, item.GetKey(), item.FailureCount + 1,
                                                 failureDescription);
                                parms.WorkQueueStatusEnum = WorkQueueStatusEnum.Failed;
                                parms.ScheduledTime = Platform.Time;
                                parms.ExpirationTime = Platform.Time.AddDays(1);

                                RaiseAlert(item, AlertLevel.Error, String.Format("Failing {0} WorkQueue entry ({1}), reached max retry count of {2}. Failure Reason: {3}",
                                                         item.WorkQueueTypeEnum, item.GetKey(), item.FailureCount + 1, failureDescription));
                            }
                            else
                            {
                                Platform.Log(LogLevel.Error,
                                             "Resetting {0} WorkQueue entry ({1}) to Pending, current retry count {2}",
                                             item.WorkQueueTypeEnum, item.GetKey(), item.FailureCount + 1);
                                parms.WorkQueueStatusEnum = WorkQueueStatusEnum.Pending;
                                    parms.ScheduledTime =
                                        Platform.Time.AddMilliseconds(settings.WorkQueueQueryDelay);
                                parms.ExpirationTime =
                                        Platform.Time.AddSeconds((WorkQueueProperties.MaxFailureCount -
                                                                  item.FailureCount) *
															 WorkQueueProperties.FailureDelaySeconds);
                            }

                            if (false == update.Execute(parms))
                            {
                                    Platform.Log(LogLevel.Error, "Unable to update {0} WorkQueue GUID: {1}",
                                                 item.WorkQueueTypeEnum,
                                             item.GetKey().ToString());
                            }
                            else
                                updateContext.Commit();
                            } 
                            #endregion
                        });
                    break; // done
                        }
                catch (Exception ex)
                {
                    
                    if (ex is PersistenceException || ex is SqlException)
                    {
                        if (retryCount > MAX_DB_RETRY)
                        {
                            Platform.Log(LogLevel.Error, ex, "Error occurred when calling FailQueueItem. Max db retry count has been reached.");
                            throw;
                    }

                        Platform.Log(LogLevel.Error, ex, "Error occurred when calling FailQueueItem. Retry later. GUID={0}", item.Key);
                        SleepForRetry();

                        // Service is stoping
                        if (CancelPending)
                        {
                            Platform.Log(LogLevel.Warn, "Stop is requested. Attempt to fail WorkQueue entry is now terminated.");
                            break;
        }
                        retryCount++;
                    }
                    else
                        throw;
                }
            }
            
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Simple routine for abort (fail) a work queue item immediately.
        /// </summary>
        /// <param name="item">The item to fail.</param>
        /// <param name="failureDescription">The reason for the failure.</param>
        /// <param name="generateAlert"></param>
        protected virtual void AbortQueueItem(Model.WorkQueue item, string failureDescription, bool generateAlert)
        {
            int retryCount = 0;
            while (true)
            {
                try
                {
                    int count = retryCount;
                    DBUpdateTime.Add(
                        delegate
                        {
                            #region Fail the WorkQueue entry
                            using (IUpdateContext updateContext = PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush))
                            {
                                if (count>0)
                                    Platform.Log(LogLevel.Error, "Abort {0} WorkQueue entry ({1}). Retry # {2}. Reason: {3}", item.WorkQueueTypeEnum, item.GetKey(), count, failureDescription);
                                else
                                    Platform.Log(LogLevel.Error, "Abort {0} WorkQueue entry ({1}). Reason: {2}", item.WorkQueueTypeEnum, item.GetKey(), failureDescription);
                                IUpdateWorkQueue broker = updateContext.GetBroker<IUpdateWorkQueue>();
                                UpdateWorkQueueParameters parms = new UpdateWorkQueueParameters
                                                                      {
                                                                          ProcessorID = ServerPlatform.ProcessorId,
                                                                          WorkQueueKey = item.GetKey(),
                                                                          StudyStorageKey = item.StudyStorageKey,
                                                                          FailureCount = item.FailureCount + 1,
                                                                          FailureDescription = failureDescription,
                                                                          WorkQueueStatusEnum = WorkQueueStatusEnum.Failed,
                                                                          ScheduledTime = Platform.Time,
                                                                          ExpirationTime = Platform.Time.AddDays(1)
                                                                      };

                                if (false == broker.Execute(parms))
                                {
                                    Platform.Log(LogLevel.Error, "Unable to update {0} WorkQueue GUID: {1}", item.WorkQueueTypeEnum, item.GetKey().ToString());
                                }
                                else
                                {
                                    updateContext.Commit();
                                }
                            }
                            #endregion
                        });
                    break; // done
                }
                catch (Exception ex)
                {

                    if (ex is PersistenceException || ex is SqlException)
                    {
                        if (retryCount > MAX_DB_RETRY)
                        {
                            Platform.Log(LogLevel.Error, ex, "Error occurred when calling AbortQueueItem. Max db retry count has been reached.");
                            throw;
                        }

                        Platform.Log(LogLevel.Error, ex, "Error occurred when calling AbortQueueItem. Retry later. GUID={0}", item.Key);
                        SleepForRetry();

                        // Service is stoping
                        if (CancelPending)
                        {
                            Platform.Log(LogLevel.Warn, "Stop is requested. Attempt to abort WorkQueue entry is now terminated.");
                            break;
                        }
                        retryCount++;
                    }
                    else
                        throw;
                }
            }

        }
Ejemplo n.º 3
0
        /// <summary>
		/// Set a status of <see cref="WorkQueue"/> item after batch processing has been completed.
		/// </summary>
		/// <remarks>
		/// <para>
		/// This routine will set the status of the <paramref name="item"/> to one of the following
		/// <list type="bullet">
		/// <item>Failed: if the current process failed and number of retries has been reached or a fatal error.</item>
		/// <item>Pending: if the number of retries has not been reached</item>
		/// </list>
		/// </para>
		/// </remarks>
		/// <param name="item">The <see cref="WorkQueue"/> item to set.</param>
		/// <param name="processorFailureType">The failure is unrecoverable</param>
		protected virtual void PostProcessingFailure(Model.WorkQueue item, WorkQueueProcessorFailureType processorFailureType)
		{
    	    int retryCount = 0;
            while (true)
            {
                try
                {
                    #region Fail the entry

			DBUpdateTime.Add(
				delegate
					{
						using (
							IUpdateContext updateContext =
								PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush))
						{
							IUpdateWorkQueue update = updateContext.GetBroker<IUpdateWorkQueue>();
							UpdateWorkQueueParameters parms = new UpdateWorkQueueParameters
							                                      {
							                                          WorkQueueKey = item.GetKey(),
							                                          StudyStorageKey = item.StudyStorageKey,
							                                          ProcessorID = item.ProcessorID
							                                      };

						    if (item.FailureDescription != null)
								parms.FailureDescription = item.FailureDescription;

							parms.FailureCount = item.FailureCount + 1;
							if (processorFailureType == WorkQueueProcessorFailureType.Fatal)
							{
								Platform.Log(LogLevel.Error,
											 "Failing {0} WorkQueue entry ({1}), fatal error: {2}",
											 item.WorkQueueTypeEnum, item.GetKey(), item.FailureDescription);

								parms.WorkQueueStatusEnum = WorkQueueStatusEnum.Failed;
								parms.ScheduledTime = Platform.Time;
								parms.ExpirationTime = Platform.Time; // expire now		

                                RaiseAlert(item, AlertLevel.Error, String.Format("Failing {0} WorkQueue entry ({1}), fatal error: {2}", item.WorkQueueTypeEnum, item.GetKey(), item.FailureDescription));
							}
							else if ((item.FailureCount + 1) > WorkQueueProperties.MaxFailureCount)
							{
								Platform.Log(LogLevel.Error,
                                             "Failing {0} WorkQueue entry ({1}), reached max retry count of {2}. Failure Reason: {3}",
											 item.WorkQueueTypeEnum, item.GetKey(), item.FailureCount + 1, item.FailureDescription);
								parms.WorkQueueStatusEnum = WorkQueueStatusEnum.Failed;
								parms.ScheduledTime = Platform.Time;
								parms.ExpirationTime = Platform.Time; // expire now


                                RaiseAlert(item, AlertLevel.Error, String.Format("Failing {0} WorkQueue entry ({1}): {2}", item.WorkQueueTypeEnum, item.GetKey(), item.FailureDescription));
							}
							else
							{
								Platform.Log(LogLevel.Error,
                                             "Resetting {0} WorkQueue entry ({1}) to Pending, current retry count {2}.",
								             item.WorkQueueTypeEnum, item.GetKey(), item.FailureCount + 1);
								parms.WorkQueueStatusEnum = WorkQueueStatusEnum.Pending;
								parms.ScheduledTime = Platform.Time.AddSeconds(WorkQueueProperties.FailureDelaySeconds);
								parms.ExpirationTime =
									   Platform.Time.AddSeconds((WorkQueueProperties.MaxFailureCount - item.FailureCount) *
									                        WorkQueueProperties.FailureDelaySeconds);
							}


							if (false == update.Execute(parms))
							{
								Platform.Log(LogLevel.Error, "Unable to update {0} WorkQueue GUID: {1}",
											 item.WorkQueueTypeEnum, item.GetKey().ToString());
							}
							else
								updateContext.Commit();
						}
					}
				);

                    break; // done
                    #endregion
		}
                catch (Exception ex)
                {
                    if (ex is PersistenceException || ex is SqlException)
                    {
                        if (retryCount > MAX_DB_RETRY)
                        {
                            Platform.Log(LogLevel.Error, ex, "Error occurred when calling PostProcessingFailure. Max db retry count has been reached.");
                            
                            // can't do anything except throwing it.
                            throw;
                        }

                        Platform.Log(LogLevel.Error, ex, "Error occurred when calling PostProcessingFailure(). Retry later. GUID={0}", item.Key);
                        SleepForRetry();

                        // If service is stoping then stop
                        if (CancelPending)
                        {
                            Platform.Log(LogLevel.Warn, "Stop is requested. Attempt to fail WorkQueue entry is now terminated.");
                            break;
                        }
                        retryCount++;
                    }
                    else
                        throw;
                }
            }
        
		}
Ejemplo n.º 4
0
		/// <summary>
		/// Set a status of <see cref="WorkQueue"/> item after batch processing has been completed.
		/// </summary>
		/// <remarks>
		/// <para>
		/// This routine will set the status of the <paramref name="item"/> to one of the followings
		/// <list type="bullet">
		/// <item>Failed: if the current process failed and number of retries has been reached.</item>
		/// <item>Pending: if the current batch has been processed successfully</item>
		/// <item>Idle : if current batch size = 0.</item>
		/// <item>Completed: if batch size =0 (idle) and the item has expired.</item>
		/// </list>
		/// </para>
		/// </remarks>
		/// <param name="item">The <see cref="WorkQueue"/> item to set.</param>
		/// <param name="status">Indicates if complete.</param>
		/// <param name="resetQueueStudyState">Reset the queue study state back to Idle</param>
		protected virtual void PostProcessing(Model.WorkQueue item, WorkQueueProcessorStatus status, WorkQueueProcessorDatabaseUpdate resetQueueStudyState)
		{
		    Completed = status == WorkQueueProcessorStatus.Complete
		                     || (status == WorkQueueProcessorStatus.Idle && item.ExpirationTime < Platform.Time);
            if (Completed)
            {
                if (WorkQueueSettings.Instance.EnableStudyIntegrityValidation)
                {
                    Platform.Log(LogLevel.Info, "{0} has completed (GUID={1})", item.WorkQueueTypeEnum, item.GetKey().Key);
                    VerifyStudy(StorageLocation);
                }
            }

			DBUpdateTime.Add(
				delegate
				{
					using (
						IUpdateContext updateContext =
							PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush))
					{
						IUpdateWorkQueue update = updateContext.GetBroker<IUpdateWorkQueue>();
						UpdateWorkQueueParameters parms = new UpdateWorkQueueParameters
						                                      {
						                                          WorkQueueKey = item.GetKey(),
						                                          StudyStorageKey = item.StudyStorageKey,
						                                          ProcessorID = item.ProcessorID
						                                      };

						DateTime now = Platform.Time;

						if (item.FailureDescription != null)
							parms.FailureDescription = item.FailureDescription;

						DateTime scheduledTime = now.AddSeconds(WorkQueueProperties.ProcessDelaySeconds);


						if (scheduledTime > item.ExpirationTime)
							scheduledTime = item.ExpirationTime;

                        if (status == WorkQueueProcessorStatus.CompleteDelayDelete)
                        {
                            parms.WorkQueueStatusEnum = WorkQueueStatusEnum.Idle;
                            parms.FailureCount = item.FailureCount;
                            parms.FailureDescription = "";
                            parms.ScheduledTime = parms.ExpirationTime = Platform.Time.AddSeconds(WorkQueueProperties.DeleteDelaySeconds);
                            if (resetQueueStudyState == WorkQueueProcessorDatabaseUpdate.ResetQueueState)
                                parms.QueueStudyStateEnum = QueueStudyStateEnum.Idle;
                        }
                        else if (status == WorkQueueProcessorStatus.Complete
							|| (status == WorkQueueProcessorStatus.Idle && item.ExpirationTime < Platform.Time))
						{
							parms.WorkQueueStatusEnum = WorkQueueStatusEnum.Completed;
							parms.FailureCount = item.FailureCount;
							parms.ScheduledTime = scheduledTime;
							if (resetQueueStudyState == WorkQueueProcessorDatabaseUpdate.ResetQueueState)
								parms.QueueStudyStateEnum = QueueStudyStateEnum.Idle;

							parms.ExpirationTime = item.ExpirationTime; // Keep the same
						    Completed = true;
						}
						else if (status == WorkQueueProcessorStatus.Idle
						      || status == WorkQueueProcessorStatus.IdleNoDelete)
						{
							scheduledTime = now.AddSeconds(WorkQueueProperties.DeleteDelaySeconds);
							if (scheduledTime > item.ExpirationTime)
								scheduledTime = item.ExpirationTime;

							parms.WorkQueueStatusEnum = WorkQueueStatusEnum.Idle;
							parms.ScheduledTime = scheduledTime;
							parms.ExpirationTime = item.ExpirationTime; // keep the same
							parms.FailureCount = item.FailureCount;
						}
						else
						{
							parms.WorkQueueStatusEnum = WorkQueueStatusEnum.Pending;

							parms.ExpirationTime = scheduledTime.AddSeconds(WorkQueueProperties.ExpireDelaySeconds);
							parms.ScheduledTime = scheduledTime;
							parms.FailureCount = item.FailureCount;
						}


						if (false == update.Execute(parms))
						{
							Platform.Log(LogLevel.Error, "Unable to update {0} WorkQueue Key: {1}", item.WorkQueueTypeEnum, item.Key.ToString());
						}
						else
							updateContext.Commit();
					}
				}
				);

		}
Ejemplo n.º 5
0
        /// <summary>
        /// Simple routine for failing a work queue item.
        /// </summary>
        /// <param name="item">The item to fail.</param>
        /// <param name="failureDescription">The reason for the failure.</param>
        protected override void FailQueueItem(Model.WorkQueue item, string failureDescription)
        {
            DBUpdateTime.Add(
                delegate
                {
                    using (IUpdateContext updateContext = PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush))
                    {
                        IUpdateWorkQueue update = updateContext.GetBroker<IUpdateWorkQueue>();
                        UpdateWorkQueueParameters parms = new UpdateWorkQueueParameters
                                                          	{
                                                          		ProcessorID = ServerPlatform.ProcessorId,
                                                          		WorkQueueKey = item.GetKey(),
                                                          		StudyStorageKey = item.StudyStorageKey,
                                                          		FailureCount = item.FailureCount + 1,
                                                          		FailureDescription = failureDescription
                                                          	};

                    	Platform.Log(LogLevel.Error,
                                     "Failing {0} WorkQueue entry ({1}): {2}", 
                                     item.WorkQueueTypeEnum, 
                                     item.GetKey(), failureDescription);

                        parms.WorkQueueStatusEnum = WorkQueueStatusEnum.Failed;
                        parms.ScheduledTime = Platform.Time;
                        parms.ExpirationTime = Platform.Time.AddDays(1);
						
                        if (false == update.Execute(parms))
                        {
                            Platform.Log(LogLevel.Error, "Unable to update {0} WorkQueue GUID: {1}", item.WorkQueueTypeEnum,
                                         item.GetKey().ToString());
                        }
                        else
                            updateContext.Commit();
                    }
                }
                );


        }
Ejemplo n.º 6
0
    	/// <summary>
        /// Simple routine for failing a work queue item.
        /// </summary>
        /// <param name="item">The item to fail.</param>
		/// <param name="failureDescription">The reason for the failure.</param>
        private void FailQueueItem(Model.WorkQueue item, string failureDescription)
        {
            // Must retry to reset the status of the entry in case of db error
            // Failure to do so will create stale work queue entry (stuck in "In Progress" state)
            // which can only be recovered by restarting the service.
            while(true) 
            {
                try
                {
                	WorkQueueTypeProperties prop = _propertiesDictionary[item.WorkQueueTypeEnum];
                    using (IUpdateContext updateContext = _store.OpenUpdateContext(UpdateContextSyncMode.Flush))
                    {
                        IUpdateWorkQueue update = updateContext.GetBroker<IUpdateWorkQueue>();
                        UpdateWorkQueueParameters parms = new UpdateWorkQueueParameters
                                                          	{
                                                          		ProcessorID = ServerPlatform.ProcessorId,
                                                          		WorkQueueKey = item.GetKey(),
                                                          		StudyStorageKey = item.StudyStorageKey,
                                                          		FailureCount = item.FailureCount + 1,
                                                          		FailureDescription = failureDescription
                                                          	};

                    	var settings = WorkQueueSettings.Instance;
                        if ((item.FailureCount + 1) > prop.MaxFailureCount)
                        {
                            Platform.Log(LogLevel.Error,
                                         "Failing {0} WorkQueue entry ({1}), reached max retry count of {2}. Failure Reason: {3}",
                                         item.WorkQueueTypeEnum, item.GetKey(), item.FailureCount + 1, failureDescription);
                            parms.WorkQueueStatusEnum = WorkQueueStatusEnum.Failed;
                            parms.ScheduledTime = Platform.Time;
                            parms.ExpirationTime = Platform.Time.AddDays(1);

                            OnWorkQueueEntryFailed(item, failureDescription);
                        }
                        else
                        {
                            Platform.Log(LogLevel.Error,
                                         "Resetting {0} WorkQueue entry ({1}) to Pending, current retry count {2}. Failure Reason: {3}",
                                         item.WorkQueueTypeEnum, item.GetKey(), item.FailureCount + 1, failureDescription);
                            parms.WorkQueueStatusEnum = WorkQueueStatusEnum.Pending;
                            parms.ScheduledTime = Platform.Time.AddMilliseconds(settings.WorkQueueQueryDelay);
                            parms.ExpirationTime =
                                Platform.Time.AddSeconds((prop.MaxFailureCount - item.FailureCount) *
                                                         prop.FailureDelaySeconds);
                        }

                        if (false == update.Execute(parms))
                        {
                            Platform.Log(LogLevel.Error, "Unable to update {0} WorkQueue GUID: {1}", item.WorkQueueTypeEnum,
                                         item.GetKey().ToString());
                        }
                        else
                        {
                            updateContext.Commit();
                            break; // done
                        }
                    }                    
                }
                catch(Exception ex)
                {
                    Platform.Log(LogLevel.Error,  "Error occurred when calling FailQueueItem. Retry later. {0}", ex.Message);
                    _terminateEvent.WaitOne(2000, false);
                    if (_stop)
                    {
                        Platform.Log(LogLevel.Warn, "Service is stopping. Retry to fail the entry is terminated.");
                        break;
                    }                        
                }                
            }
        }