private QueueManager(string catalogLocation, string persistLocation, string transitLocation, int transitCleanupInterval, int transitMaximumAge) { this.catalogLocation = catalogLocation; this.persistLocation = persistLocation; this.transitLocation = transitLocation; this.LoadQueueInfos(); this.LoadPersistedQueues(); this.transitCleanupOperation = TransitCleanupOperation.Start(this.transitLocation, transitCleanupInterval, transitMaximumAge, message => this.Get(message.QueueName).Enqueue(message)); }
/// <summary> /// Starts the transit cleanup operation. /// </summary> /// <param name="transitLocation">Folder where messages are temporarily kept during dequeue until committed.</param> /// <param name="cleanupInterval">Period in milliseconds used to scan and cleanup (i.e. re-queue) uncommitted messages.</param> /// <param name="maximumAge"> /// For uncommitted messages, the maximum number of /// milliseconds they stay that way before being cleaned up (i.e. re-queued). /// </param> /// <param name="cleanupAction">Action to perform with each uncommitted message to clean it up.</param> /// <returns>A TransitCleanupOperation object that can be used to stop the cleanup operation.</returns> public static TransitCleanupOperation Start(string transitLocation, int cleanupInterval, int maximumAge, Action<QueueMessage> cleanupAction) { var operation = new TransitCleanupOperation(); var token = operation.cancellationTokenSource.Token; var formatter = new BinaryFormatter(); var totalCleanupCount = cleanupInterval/MinimumCleanupInterval; totalCleanupCount = totalCleanupCount == 0 ? 1 : totalCleanupCount; operation.task = Task.Factory.StartNew(() => { while (true) { if (token.IsCancellationRequested) return; var now = DateTime.Now; var files = Directory.GetFiles(transitLocation, "*.qm") .Select(x => new FileInfo(x)) .Where(x => now.Subtract(x.CreationTime).TotalMilliseconds > maximumAge) .Select(x => x.FullName); foreach (var file in files) { QueueMessage message; using (var fs = File.OpenRead(file)) { message = (QueueMessage) formatter.Deserialize(fs); } File.Delete(file); cleanupAction(message); } if (token.IsCancellationRequested) return; var cleanupCount = 0; while (cleanupCount < totalCleanupCount) { Thread.Sleep(MinimumCleanupInterval); cleanupCount++; if (token.IsCancellationRequested) return; } } }, token); return operation; }