private JobStatus CreateJobStatus(CloudQueueMessage message) { return(new JobStatus { QueueName = QueueProxy.GetQueue().Name, MessageId = message.Id, Success = true, RunDateTime = DateTime.UtcNow, Message = message.AsString }); }
/// <summary> /// Starts the worker task. /// </summary> public override void OnStart() { QueueProxy.GetQueue().CreateIfNotExists(); base.OnStart(); //start timers }
/// <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> /// Processes a notification queue and sends the notification email. /// </summary> /// <param name="message"></param> /// <returns></returns> public override bool ProcessMessage(CloudQueueMessage message) { var change = QueueProxy.DeserializeRecordChangeNotification(message); var msg = new MailMessage(); msg.To.Add(change.PartitionKey); msg.From = new MailAddress(FromAddress, FromAddress); msg.IsBodyHtml = true; msg.Priority = MailPriority.Normal; var user = ProviderResolver <UserProvider> .Get.Provider.GetUserByName(change.PartitionKey); var emailAddress = change.PartitionKey; try { if (user == null) { msg.Subject = "Temporary Password - No Account found"; var template = _razorMachine.ExecuteUrl("~/Account/ForgotPasswordNoUser", new { UserName = emailAddress }); msg.Body = template.Result; if (string.IsNullOrWhiteSpace(msg.Body)) { LogProvider.Error("No email body generated for /Views/Account/ForgotPasswordNoUser.cshtml"); return(true); //this is very likely on purpose. } } else { var resetCode = ProviderResolver <UserProvider> .Get.Provider.GenerateUserResetCode(emailAddress); user.PasswordHash = resetCode; msg.Subject = "Temporary Password"; var template = _razorMachine.ExecuteUrl("~/Account/ForgotPassword", user); msg.Body = template.Result; if (string.IsNullOrWhiteSpace(msg.Body)) { LogProvider.Error("No email body generated for /Views/Account/ForgotPassword.cshtml"); return(false); } } } catch (Exception exBody) { LogProvider.ErrorFormat("Failed to generate body for password reset to email to address '{0}'; User:{1};", exBody, emailAddress, user != null); return(false); } var client = new SmtpClient { Host = SmtpServer, Port = Port }; if (SmtpUserName.Length > 0) { client.Credentials = new NetworkCredential(SmtpUserName, SmtpPassword); } // try to send Mail try { client.Send(msg); return(true); } catch (Exception ex) { LogProvider.ErrorFormat("Failed to send password reset to email to address '{0}'; User:{1}", ex, emailAddress, user != null); return(false); } }