Пример #1
0
		/// <summary>
		/// Obtains the first available task from the specified queue, and changes the client's
		/// state into TaskReserved. In that state, no new tasks can be reserved until the 
		/// task's outcome is evident.
		/// </summary>
		/// <param name="queue"></param>
		/// <returns></returns>
		public TaskMessage Reserve(QueueName queue)
		{
			if (_state == RedisQueueState.TaskReserved)
				throw new TaskAlreadyReservedException("Cannot reserve multiple tasks at once.");

			if (string.IsNullOrEmpty(queue.ToString()))
				throw new NoQueueSpecifiedException(
					"Parameter <queue> is empty or null. Cannot retrieve task for no queue.");

			if (_taskMessageClient.Lists[queue.NameWhenPending].Count == 0)
				throw new QueueIsEmptyException("No tasks available in specified queue.");

			CurrentTask = _taskMessageClient.Lists[queue.NameWhenPending].RemoveStart();
			_state = RedisQueueState.TaskReserved;

			_log.Info("Reserved task from [" + queue.NameWhenPending + "]");
			_log.DebugFormat("Task Parameters: {0}", CurrentTask.Parameters);

			return CurrentTask;
		}
Пример #2
0
		/// <summary>
		/// Marks the current task as failed, and regardless of the cycling setting, places it 
		/// in the :failed queue.
		/// </summary>
		/// <param name="reason"></param>
		public void CriticalFail(string reason)
		{
			if (_state != RedisQueueState.TaskReserved)
				throw new NoTaskReservedException("No task has been reserved. Future failure not yet supported.");

			if (CurrentTask == null)
				throw new InvalidStateException("CurrentTask is null. Something's seriously off.");

			CurrentTask.Status = TaskStatus.Failed;
			CurrentTask.Reason = reason;
			CurrentTask.UpdatedOn = DateTime.Now;

			var targetQueue = new QueueName(CurrentTask.Queue).NameWhenFailed;

			_taskMessageClient.Lists[targetQueue].Add(CurrentTask);

			_log.Info("A task has failed. Moving to [" + targetQueue + "].");
			_log.DebugFormat("Task Parameters: {0}", CurrentTask.Parameters);

			_state = RedisQueueState.Ready;
		}
Пример #3
0
		/// <summary>
		/// Marks the currently reserved task as succeeded.
		/// </summary>
		/// <exception cref="InvalidStateException">CurrentTask is null. Something's seriously off.</exception>
		/// <exception cref="NoTaskReservedException">No task has been reserved. Future success not yet 
		/// supported.</exception>
		public void Succeed()
		{
			if (_state != RedisQueueState.TaskReserved)
				throw new NoTaskReservedException(
					"No task has been reserved. Future success not yet supported.");

			if (CurrentTask == null)
				throw new InvalidStateException("CurrentTask is null. Something's seriously off.");

			CurrentTask.Status = TaskStatus.Succeeded;
			CurrentTask.UpdatedOn = DateTime.Now;

			if (!Settings.Default.PurgeSuccessfulTasks)
			{
				var queue = new QueueName(CurrentTask.Queue);
				_taskMessageClient.Lists[queue.NameWhenSucceeded].Add(CurrentTask);
				_log.Info("A task has succeeded. Moving to [" + queue.NameWhenSucceeded + "].");
			}
			else
			{
				_log.Info("A task has succeeded and will be dropped.");
			}

			_log.DebugFormat("Task Parameters: {0}", CurrentTask.Parameters);

			_state = RedisQueueState.Ready;
		}
Пример #4
0
		/// <summary>
		/// Marks the currently reserved task as failed.
		/// </summary>
		/// <param name="reason"></param>
		/// <exception cref="NoTaskReservedException">No task has been reserved. Future failure not yet 
		/// supported.</exception>
		/// <exception cref="InvalidStateException">CurrentTask is null. Something's seriously off.</exception>
		public void Fail(string reason)
		{
			if (_state != RedisQueueState.TaskReserved)
				throw new NoTaskReservedException("No task has been reserved. Future failure not yet supported.");

			if (CurrentTask == null)
				throw new InvalidStateException("CurrentTask is null. Something's seriously off.");

			CurrentTask.Status = TaskStatus.Failed;
			CurrentTask.Reason = reason;
			CurrentTask.UpdatedOn = DateTime.Now;

			var queue = new QueueName(CurrentTask.Queue);
			var targetQueue = queue.NameWhenFailed;

			// If we support task cycling and the task should indeed be recycled, 
			// place it to the end of the pending queue again.
			if (Settings.Default.TaskRecycling)
				if (Settings.Default.MaxTaskRetries == 0 || CurrentTask.Retries < Settings.Default.MaxTaskRetries)
				{
					targetQueue = queue.NameWhenPending;

					// If we support cycling, and we have a limit to how many times tasks
					// can be recycled, keep track of the number of retries. Do not remove this
					// lightly, since it can produce arithmetic overflows (<TaskMessage>.Retries is
					// an int, after all).
					if (CurrentTask.Retries < Settings.Default.MaxTaskRetries) CurrentTask.Retries++;
				}

			_taskMessageClient.Lists[targetQueue].Add(CurrentTask);

			_log.Info("A task has failed. Moving to [" + targetQueue + "].");
			_log.DebugFormat("Task Parameters: {0}", CurrentTask.Parameters);

			_state = RedisQueueState.Ready;
		}