public void TestHostUnreachableResponseTime() { RedisServer.Kill(); var stopWatch = new Stopwatch(); try { using (var client = new QueueClient()) { var homemadeTask = new TaskMessage { Parameters = "params", Queue = "TestQueue" }; stopWatch.Start(); client.Enqueue(homemadeTask); stopWatch.Stop(); } } catch (Exception exception) { Console.WriteLine("Elapsed time: {0} ms", stopWatch.ElapsedMilliseconds); Console.WriteLine(exception.ToString()); RedisServer.Start(); Assert.Pass(); } }
/// <summary> /// Adds a task to the queue specified in the task itself and sends a message to /// the associated channel, notifying any listeners. /// </summary> /// <param name="t"></param> public void Enqueue(TaskMessage t) { if (string.IsNullOrEmpty(t.Queue)) throw new NoQueueSpecifiedException( "TaskMessage.Queue is empty or null. Cannot append task to queue."); var queue = new QueueName(t.Queue); TypedClient.Lists[queue.NameWhenPending].Add(t); SendMessage(QueueSystemMessages.TaskAvailable.ToString(), queue); Log.Info("New task in [" + queue.NameWhenPending + "]"); Log.DebugFormat("Task Parameters: {0}", t.Parameters); }
public void TestCachingCreatesAFile() { using (var client = new QueueClient()) { var homemadeTask = new TaskMessage { Parameters = "params", Queue = "TestQueue" }; client.Enqueue(homemadeTask); var retrievedTask = client.Reserve("TestQueue"); Assert.That(File.Exists("redisCache.bin")); client.Fail(string.Empty); client.RemoveTask(client.AllTasks("TestQueue")[0]); } }
public void TestCanEnqueueTaskInRedisAndReadItBack() { using(var client = new QueueClient()) { var homemadeTask = new TaskMessage { Parameters = "params", Queue = "TestQueue" }; client.Enqueue(homemadeTask); var retrievedTask = client.Reserve("TestQueue"); Assert.AreEqual(retrievedTask.Parameters, homemadeTask.Parameters); Assert.AreEqual(retrievedTask.Queue, homemadeTask.Queue); client.Fail(string.Empty); client.RemoveTask(client.AllTasks("TestQueue")[0]); } }
public void TestProcessTaskWithNullTaskStorageSucceeds() { var monitor = new RedisMonitor(); var task = new TaskMessage { Parameters = "Test Params", Queue = "TestQueue" }; // Setup the Performer mock. var performerMock =new Mock<Performer>(); performerMock.Setup(x => x.Perform(task.Parameters)); performerMock.SetupGet(x => x.Status).Returns(new PerformResult { Data = string.Empty, Outcome = Outcome.Success, Reason = string.Empty }); // Setup the Client mock. var clientMock = new Mock<QueueClient>(); clientMock.Setup(x => x.Succeed()); clientMock.SetupGet(x => x.RedisHost).Returns("127.0.0.1"); clientMock.SetupGet(x => x.RedisPort).Returns(6379); monitor.Performer = performerMock.Object; monitor.MonitorClient = clientMock.Object; monitor.ProcessTask(task); Assert.That(performerMock.Object.TaskStorage == null); performerMock.Verify(x => x.Perform(task.Parameters)); performerMock.VerifyGet(x => x.TaskStorage); performerMock.VerifyGet(x => x.Status); clientMock.Verify(x => x.Succeed()); }
public void TestMonitorCanRecoverFromRedisOutage() { var task = new TaskMessage { Parameters = "blah", Queue = "TestQueue" }; var task2 = new TaskMessage { Parameters = "blah", Queue = "TestQueue" }; var performerMock = new Mock<Performer>(); performerMock.SetupGet(x => x.Status).Returns(new PerformResult { Data = string.Empty, Outcome = Outcome.Success, Reason = string.Empty }); performerMock.Setup(x => x.Perform(task.Parameters)); performerMock.Setup(x => x.Perform(task2.Parameters)); var monitor = new RedisMonitor(); monitor.Performer = performerMock.Object; monitor.Start(); Assert.IsTrue(monitor.Running); using (var client = new QueueClient()) client.Enqueue(task); Thread.Sleep(1500); RedisServer.Kill(); Thread.Sleep(100); RedisServer.Start(); Thread.Sleep(2000); using (var client = new QueueClient()) client.Enqueue(task2); Thread.Sleep(10000); monitor.Stop(); Assert.IsFalse(monitor.Running); }
public void TestCachingCanPreserveTask() { using (var client = new QueueClient()) { var homemadeTask = new TaskMessage { Parameters = "params", Queue = "TestQueue" }; client.Enqueue(homemadeTask); var retrievedTask = client.Reserve("TestQueue"); } using (var client = new QueueClient()) { Assert.That(client.CurrentTask != null); client.Fail(string.Empty); client.RemoveTask(client.AllTasks("TestQueue")[0]); } }
public void TestProcessPendingTasksForMultipleTasksMockingPerformerOnly() { #region Prepare Tasks and mock Performer for processing var monitor = new RedisMonitor(); var performerMock = new Mock<Performer>(); using (var client = new QueueClient()) { for (var i = 0; i < 10; i++) { var task = new TaskMessage { Parameters = "Task " + i, Queue = "TestQueue" }; client.Enqueue(task); performerMock.Setup(x => x.Perform(task.Parameters)); } } // ensure all tasks will be successful. performerMock.SetupGet(x => x.Status).Returns(new PerformResult { Data = string.Empty, Outcome = Outcome.Success, Reason = string.Empty }); #endregion monitor.Performer = performerMock.Object; monitor.Start(); Thread.Sleep(2000); monitor.Stop(); for (var i = 0; i < 10; i++) performerMock.Verify(x => x.Perform("Task " + i)); performerMock.VerifyGet(x => x.TaskStorage); performerMock.VerifyGet(x => x.Status); using(var client = new QueueClient()) Assert.AreEqual(client.PendingTasks("TestQueue").Count, 0); }
public void TestMonitorWakesUpOnMessageReceived() { var task = new TaskMessage { Parameters = "blah", Queue = "TestQueue" }; var performerMock = new Mock<Performer>(); performerMock.SetupGet(x => x.Status).Returns(new PerformResult { Data = string.Empty, Outcome = Outcome.Success, Reason = string.Empty }); performerMock.Setup(x => x.Perform(task.Parameters)); var monitor = new RedisMonitor(); monitor.Performer = performerMock.Object; var start = DateTime.Now; monitor.Start(); Assert.IsTrue(monitor.Running); using (var client = new QueueClient()) client.Enqueue(task); monitor.Stop(); Assert.IsFalse(monitor.Running); var stop = DateTime.Now; Assert.Less((stop - start).TotalSeconds, 60); }
public void TestProcessTaskWhenTaskPerformerThrowsException() { var monitor = new RedisMonitor(); var task = new TaskMessage { Parameters = "Test Params", Queue = "TestQueue" }; // Setup the Performer mock. var performerMock =new Mock<Performer>(); var exception = new Exception("Test"); performerMock.Setup(x => x.Perform(task.Parameters)).Throws(exception); performerMock.SetupGet(x => x.Status).Returns(new PerformResult { Data = string.Empty, Outcome = Outcome.Success, Reason = string.Empty }); // Setup the Client mock. var clientMock = new Mock<QueueClient>(); clientMock.SetupGet(x => x.RedisHost).Returns("127.0.0.1"); clientMock.SetupGet(x => x.RedisPort).Returns(6379); clientMock.Setup(x => x.Fail( "The performer raised an exception: " + exception.Message + "\n" + exception.StackTrace)); monitor.Performer = performerMock.Object; monitor.MonitorClient = clientMock.Object; monitor.ProcessTask(task); performerMock.Verify(x => x.Perform(task.Parameters)); performerMock.VerifyGet(x => x.TaskStorage); clientMock.Verify(x => x.Fail( "The performer raised an exception: " + exception.Message + "\n" + exception.StackTrace)); }
public void TestProcessTaskCriticalFailure() { var monitor = new RedisMonitor(); var task = new TaskMessage { Parameters = "Test Params", Queue = "TestQueue" }; // Setup the Performer mock. var performerMock = new Mock<Performer>(); performerMock.Setup(x => x.Perform(task.Parameters)); performerMock.SetupGet(x => x.Status).Returns(new PerformResult { Data = string.Empty, Outcome = Outcome.CriticalFailure, Reason = "blah" }); // Setup the Client mock. var clientMock = new Mock<QueueClient>(); clientMock.Setup(x => x.CriticalFail("blah")); clientMock.SetupGet(x => x.RedisHost).Returns("127.0.0.1"); clientMock.SetupGet(x => x.RedisPort).Returns(6379); monitor.Performer = performerMock.Object; monitor.MonitorClient = clientMock.Object; monitor.ProcessTask(task); performerMock.Verify(x => x.Perform(task.Parameters)); performerMock.VerifyGet(x => x.TaskStorage); clientMock.Verify(x => x.CriticalFail("blah")); }
/// <summary> /// Processes a single task and updates the queue accordingly. /// </summary> /// <param name="task"></param> protected internal void ProcessTask(TaskMessage task) { // Get the state of the task into the performer. Performer.TaskStorage = task.Storage; // Let the performer have a go with the task. try { Performer.Perform(task.Parameters); } catch (Exception exception) { // The performer has raised an exception while processing // the task. We do what we can to preserve the task, // and set it back as failed. try { task.Storage = Performer.TaskStorage; } catch {} var message = "The performer raised an exception: " + exception.Message + "\n" + exception.StackTrace; MonitorClient.Fail(message); Log.Error(message); return; } // Collect the task's state and save it back to the task. task.Storage = Performer.TaskStorage; // Collect the result of the perfomer's work and act on it. var result = Performer.Status; switch (result.Outcome) { case Outcome.Success: MonitorClient.Succeed(); Log.Info("Task succeeded."); break; case Outcome.Failure: MonitorClient.Fail(result.Reason); Log.InfoFormat("Task failed. Reason: {0}", result.Reason); if (result.Data is Exception) Log.Error("Exception associated with task failure:", result.Data as Exception); if (result.Data is string) Log.InfoFormat("Additional Information: {0}", result.Data); break; case Outcome.CriticalFailure: MonitorClient.CriticalFail(result.Reason); Log.InfoFormat("Task failed critically. Reason: {0}", result.Reason); if (result.Data is string) Log.InfoFormat("Additional Information: {0}", result.Data); break; } }
public void TestHostDifferentPort() { var stopWatch = new Stopwatch(); try { using (var client = new QueueClient("localhost", 6377, false)) { var homemadeTask = new TaskMessage { Parameters = "params", Queue = "TestQueue" }; stopWatch.Start(); client.Enqueue(homemadeTask); stopWatch.Stop(); } } catch (Exception exception) { Console.WriteLine("Elapsed time: {0} ms", stopWatch.ElapsedMilliseconds); Console.WriteLine(exception.ToString()); Assert.Pass(); } }
public bool Equals(TaskMessage other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return Equals(other._queue, _queue) && other.Identifier.Equals(Identifier) && Equals(other.Parameters, Parameters); }
public void TestWriteLatencyForDifferentPayloads() { var stopWatch = new Stopwatch(); using (var client = new QueueClient()) { // Small message var homemadeTask = new TaskMessage { Parameters = RandomString(1024), Queue = "TestQueue" }; stopWatch.Start(); client.Enqueue(homemadeTask); stopWatch.Stop(); Console.WriteLine("1K Message write latency (no network included): {0} ms", stopWatch.ElapsedMilliseconds); // Medium message homemadeTask = new TaskMessage { Parameters = RandomString(1024 * 10), Queue = "TestQueue" }; stopWatch.Start(); client.Enqueue(homemadeTask); stopWatch.Stop(); Console.WriteLine("10K Message write latency (no network included): {0} ms", stopWatch.ElapsedMilliseconds); // Large message homemadeTask = new TaskMessage { Parameters = RandomString(1024 * 100), Queue = "TestQueue" }; stopWatch.Start(); client.Enqueue(homemadeTask); stopWatch.Stop(); Console.WriteLine("100K Message write latency (no network included): {0} ms", stopWatch.ElapsedMilliseconds); } }
/// <summary> /// Adds a task to the queue specified in the task itself and sends a message to /// the associated channel, notifying any listeners. /// </summary> /// <param name="t"></param> public void Enqueue(TaskMessage t) { if (string.IsNullOrEmpty(t.Queue)) throw new NoQueueSpecifiedException( "TaskMessage.Queue is empty or null. Cannot append task to queue."); var queue = new QueueName(t.Queue); try { TypedClient.Lists[queue.NameWhenPending].Add(t); SendMessage(QueueSystemMessages.TaskAvailable.ToString(), queue); Log.Info("New task in [" + queue.NameWhenPending + "]"); Log.DebugFormat("Task Parameters: {0}", t.Parameters); } catch (IOException) { TasksNotEnqueuedLog.Info(new JsonSerializer<TaskMessage>().SerializeToString(t)); throw; } catch (RedisException) { TasksNotEnqueuedLog.Info(new JsonSerializer<TaskMessage>().SerializeToString(t)); throw; } }
private void removeTask(string queue, TaskMessage task) { var results = new List<TaskMessage>(); TaskMessage t; while ((t = TypedClient.Lists[queue].RemoveStart()) != null) { if (t.Equals(task)) continue; results.Add(t); } if (results.Count > 0) TypedClient.Lists[queue].AddRange(results); }
/// <summary> /// Removes a task with a specific task identifier. /// </summary> /// <param name="task"></param> public void RemoveTask(TaskMessage task) { var queueName = new QueueName(task.Queue); removeTask(queueName.NameWhenPending, task); removeTask(queueName.NameWhenFailed, task); removeTask(queueName.NameWhenSucceeded, task); }