/// <summary> /// Default constructor. /// </summary> public ServiceMailer() { // get the path to the directory for queuing messages if (queueDir == null) { queueDir = HttpContext.Current.Server.MapPath("/") + ConfigurationSettings.AppSettings[CONFIG_QUEUE_DIR]; } // get the path to the directory for failed queue messages if (failedDir == null) { failedDir = HttpContext.Current.Server.MapPath("/") + ConfigurationSettings.AppSettings[CONFIG_QUEUE_FAILED_DIR]; } // get the time interval for checking the queue -- value // in config file is minutes, so convert to milliseconds if (queueCheckTime == 0) { try { queueCheckTime = int.Parse(ConfigurationSettings.AppSettings[CONFIG_QUEUE_CHECK_TIME]); //* 60 * 1000; } catch (Exception e) { LogManager.GetCurrentClassLogger().Error( errorMessage => errorMessage("Parse of queueCheckTime failed."), e); } } // set up the FileQueue for queuing failed requests if (queue == null) { queue = new FileQueue(queueDir, queueCheckTime, this.ProcessQueueEntry); try { queue.MaxAttempts = int.Parse(ConfigurationSettings.AppSettings[CONFIG_MAX_ATTEMPTS]); } catch (Exception e) { queue.MaxAttempts = 0; } queue.MaxAttemptsHandler = this.MaxedOutQueueEntry; } }
/// <summary> /// Checks the queue directory for any entries and if there are entries attempts /// to process them. This is the method called by the <c>Timer</c> to /// periodically process the queue. /// </summary> /// <param name="stateInfo">The <c>QueueInfo</c> containing the state /// information of the <c>FileQueue</c> from which the Timer that /// is calling this method originated.</param> private static void CheckQueue( Object stateInfo) { QueueInfo queueInfo = (QueueInfo)stateInfo; FileQueue fileQueue = new FileQueue(queueInfo); bool hadError = false; LogManager.GetCurrentClassLogger().Info( infoMessage => infoMessage("===== Checking Queue =====")); DirectoryInfo dirInfo = new DirectoryInfo(queueInfo.queueLocation); // get the list of files in the queue directory FileInfo[] files = dirInfo.GetFiles("*.txt"); // for each queued file... foreach (FileInfo info in files) { try { StreamReader reader = info.OpenText(); FileQueueEntry entry = new FileQueueEntry(); entry.SetFileName(info.Name); int keyLineCnt = 0; // continue while there is more stuff in the file while (reader.Peek() >= 0) { try { // read the next line of the file String line = reader.ReadLine(); // find the position of the key/value delimiter int delimPos = line.IndexOf(FileQueueEntry.QUEUE_FILE_DELIMITER); String key = line.Substring(0, delimPos); String val = line.Substring(delimPos + FileQueueEntry.QUEUE_FILE_DELIMITER.Length); // set the attributes of the queue entry from the // queued file if (key == FileQueueEntry.Q_LABEL_QUEUE_TIME) { entry.SetQueuedTime(DateTime.Parse(val)); keyLineCnt++; } else if (key == FileQueueEntry.Q_LABEL_ATTEMPT_CNT) { entry.SetAttempts(int.Parse(val)); keyLineCnt++; } else if (key == FileQueueEntry.Q_LABEL_LAST_TIME) { entry.SetLastAttemptTime(DateTime.Parse(val)); keyLineCnt++; } else { entry[key] = val; } } catch (Exception e) { hadError = true; LogManager.GetCurrentClassLogger().Error( errorMessage => errorMessage("FileQueue.CheckQueue 1: "), e); } } reader.Close(); bool processed = false; // if the entry was successfully processed, removed it // from the queue try { if (!hadError && queueInfo.processingMethod(entry)) { fileQueue.Dequeue(entry); processed = true; } } catch (Exception e) { LogManager.GetCurrentClassLogger().Error( errorMessage => errorMessage("Error processing queue entry: "), e); } // if the entry was not successfully processed, first // see if we have reached the max # of attempts and it // so, call the MaxAttemptsHandler, otherwise update // the entry info // also, make sure we at least read the key // lines required to maintain the queue entry (beyond 3 // is application data) if (!processed && (keyLineCnt >= 3)) { entry.SetAttempts(entry.Attempts + 1); entry.SetLastAttemptTime(DateTime.Now); fileQueue.WriteQueueEntry(entry); // if there is a max attempts set and we've reached it // call the handler method (if one is defined) for max attempts // and remove the entry from the queue if ((queueInfo.maxAttempts > 0) && (entry.Attempts >= queueInfo.maxAttempts)) { if (queueInfo.maxAttemptsMethod != null) { queueInfo.maxAttemptsMethod(entry); } fileQueue.Dequeue(entry); } } } catch (Exception e) { LogManager.GetCurrentClassLogger().Error( errorMessage => errorMessage("FileQueue.CheckQueue 2: "), e); } } LogManager.GetCurrentClassLogger().Info( infoMessage => infoMessage("===== End Queue Check =====")); }