private JobStatus CreateJobStatus(CloudQueueMessage message) { return(new JobStatus { QueueName = QueueProxy.GetQueue().Name, MessageId = message.Id, Success = true, RunDateTime = DateTime.UtcNow, Message = message.AsString }); }
/// <summary> /// Continues processing after the waiting period has elapsed. /// </summary> public override IterationResult OnWaitingPeriodElapsedAdvanced() { var queue = QueueProxy.GetQueue(); while (IsRunning) { CloudQueueMessage message = null; try { CheckIn(); message = queue.GetMessage(); if (message == null) { return(new IterationResult()); } var statEntity = MessageStatusTableProxy.Get(queue.Name.GetValidPartitionKey(), string.Format("M|{0}|S|{1}", message.Id, false)); var status = statEntity != null && statEntity.Entity != null ? statEntity.Entity : CreateJobStatus(message); if (MessageFailedSkipSeconds > double.Epsilon && !status.Success && status.RunDateTime > DateTime.UtcNow.AddSeconds(-1 * MessageFailedSkipSeconds)) { //do this here in case it was long running on error, so we dequeue it one extra time before hiding it. var hideDuration = (DateTime.UtcNow - status.RunDateTime.AddSeconds(MessageFailedSkipSeconds)).Duration(); queue.UpdateMessage(message, hideDuration, MessageUpdateFields.Visibility); continue; //skip this message temporarily and continue with the next. } //this lets us know the processing has started. StatusLatestTableProxy.InsertOrUpdate(status); CheckIn(); var result = ProcessMessageAdvanced(message, status); CheckIn(); status.Success = result.Success; status.RunDateTime = DateTime.UtcNow; if (status.Success) { queue.DeleteMessage(message); } else //log status record for failed processing { //record every failure by date/time StatusTableProxy.InsertOrUpdate(status); //in another table, record latest failure only for each message. MessageStatusTableProxy.InsertOrUpdate(status); } //always update latest status for this queue StatusLatestTableProxy.InsertOrUpdate(status); if (result.DelayNextMessageSeconds > Double.Epsilon) { return new IterationResult { NextWaitingPeriodSeconds = result.DelayNextMessageSeconds } } ; } catch (OperationCanceledException e) { if (!IsRunning) { continue; } LogProvider.Info(e.Message); throw; } catch (Exception ex) { LogProvider.Error("Unhandled exception.", ex); if (message == null) { continue; } var errorStatus = CreateJobStatus(message); errorStatus.Success = false; errorStatus.LogMessage = ex.ToString(); MessageStatusTableProxy.InsertOrUpdate(errorStatus); } } return(new IterationResult()); }
/// <summary> /// Starts the worker task. /// </summary> public override void OnStart() { QueueProxy.GetQueue().CreateIfNotExists(); base.OnStart(); //start timers }