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
 }