public static void SequentialTest() { ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); var m = new MemoryQueue(); int taskCount = 100; ITask[] tasks = new ITask[taskCount]; PromiseTaskResultHandle <int>[] handles = new PromiseTaskResultHandle <int> [taskCount]; for (int i = 0; i < taskCount; i++) { var add = new AddTask(new (i, i + 1)); tasks[i] = add; var handle = new PromiseTaskResultHandle <int>(add, redis, (o) => Console.WriteLine($"result is ready: {o}")); add.BindPromise(handle.GetPromise()); m.Enqueue(add.Serialize()); handles[i] = handle; } var resolver = new RedisPromiseServer(redis); // promises resolved in a sequential manner. like one worker is processing all of them for (int i = 0; i < taskCount; i++) { var task = new DefaultTaskDeserializer().Deserialize((string)m.Dequeue()); task.Execute(); var res = task.SerializeResult(); // thanks to BindPromise each task's instance id is also id of its related promise. So we can directly resolve related promise by using it. resolver.Resolve(task.GetInstanceIdentifier(), res); } Thread.Sleep(1000); }
public SimpleWorker(IDotQueue <ITask> q, ITaskResultStore <string> r) { queue = q; resultStore = r; deserializer = new DefaultTaskDeserializer(); promiseResolver = new RedisPromiseServer(); _taskRegistry = TaskRegistry.TaskRegistry.Instance; _taskRegistry.DiscoverTasks(); }
public static void CreatePromiseTest() { ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); var m = new MemoryQueue(); int taskCount = 100; ITask[] tasks = new ITask[taskCount]; PromiseTaskResultHandle <int>[] handles = new PromiseTaskResultHandle <int> [taskCount]; for (int i = 0; i < taskCount; i++) { var add = new AddTask(new (i, i + 1)); tasks[i] = add; var client = RedisPromiseClientFactory.GetInstance(redis); var promise = client.CreatePromise(); add.BindPromise(promise); var handle = new PromiseTaskResultHandle <int>(add, promise, (o) => Console.WriteLine($"result is ready: {o}")); //now promise will be ready to resolve client.Listen(promise); m.Enqueue(add.Serialize()); handles[i] = handle; } var resolver = new RedisPromiseServer(redis); // this is simulating many workers are resolving promises. (executing tasks in this context) Parallel.ForEach(handles, ((handle) => { var task = new DefaultTaskDeserializer().Deserialize((string)m.Dequeue()); task.Execute(); var res = task.SerializeResult(); // thanks to BindPromise each task's instance id is also id of its related promise. So we can directly resolve related promise by using it. resolver.Resolve(task.GetInstanceIdentifier(), res); })); for (int i = 0; i < taskCount; i++) { int correctResult = i + i + 1; while (!handles[i].IsResolved()) { // it might not come from redis yet Thread.Sleep(10); } var calculatedResult = (int)handles[i].GetObjectResult(); if (correctResult != calculatedResult) { throw new Exception("wrong result"); } } Console.WriteLine("ParallelTest is Successful"); Thread.Sleep(1000); }
public ITask Dequeue() { var deserializer = new DefaultTaskDeserializer(); var obj = _list.Rpop(); if (obj.IsNull) { throw new QueueIsEmptyException(); } return(deserializer.Deserialize(obj.ToString())); }
public void ParallelUnitTest() { ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost"); var m = new MemoryQueue(); RedisPromiseClient promiseClient = new RedisPromiseClient(redis); int taskCount = 100; ITask[] tasks = new ITask[taskCount]; PromiseTaskResultHandle <int>[] handles = new PromiseTaskResultHandle <int> [taskCount]; for (int i = 0; i < taskCount; i++) { var add = new AddTask(new (i, i + 1)); tasks[i] = add; var handle = new PromiseTaskResultHandle <int>(add, redis); handle.Listen(promiseClient); m.Enqueue(add.Serialize()); handles[i] = handle; } var resolver = new RedisPromiseServer(redis); // this is simulating many workers are resolving promises. (executing tasks in this context) Parallel.ForEach(handles, ((handle) => { var task = new DefaultTaskDeserializer().Deserialize((string)m.Dequeue()); task.Execute(); var res = task.SerializeResult(); // thanks to BindPromise each task's instance id is also id of its related promise. So we can directly resolve related promise by using it. resolver.Resolve(task.GetInstanceIdentifier(), res); })); for (int i = 0; i < taskCount; i++) { int correctResult = i + i + 1; while (!handles[i].IsResolved()) { // it might not come from redis yet Thread.Sleep(10); } var calculatedResult = (int)handles[i].GetObjectResult(); Assert.Equal(correctResult, calculatedResult); } }
static void TestTaskExecuting() { Console.WriteLine("Hello World!"); var m = new MemoryQueue(); var mult = new MultiplyTask(new Inp { x = 4, y = 5 }); var mult2 = new MultiplyTask(new Inp { x = 4, y = 56 }); var add = new AddTask(new (5, 6)); var swap = new SwapTask(new ("abi", "naber")); var concat = new ConcatTask(new Inp2 { x = new List <string> { "f", "u", "r", "k", "a", "n" } }); var matrix = new Matrix(); matrix.nums = new int[100, 100]; var matrixSum = new MatrixSum(matrix); //TestClient(); m.Enqueue(mult.Serialize()); m.Enqueue(mult2.Serialize()); m.Enqueue(add.Serialize()); m.Enqueue(swap.Serialize()); m.Enqueue(concat.Serialize()); m.Enqueue(matrixSum.Serialize()); // normally these will happen in workers. workers will execute tasks and store their results in // result store. Client will have an TaskResult handle which will update its content when result is ready. // below res1 will be all client have. This program.cs is only for testing purposes normally workers and // client will be different processes. /* Normally it will look like this; * * For Client: * * TaskResult mult=new MultiplyTask(new Inp{x=4,y=5}); this will enqueue task, will get the handle from store(or somewhere else) * TaskResult.result == null => will be true until result is executed by some worker * * For workers: each worker will dequeue from TaskStore and push results to ResultStore like; * * ITask task = queue.Dequeue(); * task.Execute() * resultStore.SetResultOfTask(task); */ Console.WriteLine("tasks queued"); Console.WriteLine("task will be dequed. Now cleaning task registry to simulate a server..."); var registry = (ITaskRegistry)TaskRegistry.Instance; registry.Clear(); registry.DiscoverTasks(); for (long i = m.Length(); i > 0; i--) { string serialized = (string)m.Dequeue(); Console.WriteLine($"dequed task: {serialized}"); var task = new DefaultTaskDeserializer().Deserialize(serialized); Console.WriteLine("task is executing..."); task.Execute(); Console.WriteLine($"time elapsed: {task.GetTimeElapsed().Value.TotalMilliseconds} ms"); } var x = "x"; }