/// <summary> /// First creates promise and wraps it with a taskResultHandle. /// Then starts to listen for promise to resolve. /// Then enqueues task for a worker to execute task and resolve the promise. /// </summary> /// <param name="dotqApi"></param> /// <param name="task"></param> /// <typeparam name="TIn"></typeparam> /// <typeparam name="TOut"></typeparam> /// <returns></returns> public static ITaskResultHandle <TOut> Delay <TIn, TOut>(this DotqApi dotqApi, DotTask <TIn, TOut> task) // this method is written as extension method since I do not want DotqApi to be a generic class. It should be concrete { var handle = new PromiseTaskResultHandle <TOut>(task); handle.Listen(dotqApi._redisPromiseClient); dotqApi._taskQueue.Enqueue(task); return(handle); }
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); } }
public static PromiseTaskResultHandle <TOut> DelayHandle <TOut>(this DotqApi dotqApi, PromiseTaskResultHandle <TOut> handle) { handle.Listen(dotqApi._redisPromiseClient); handle.Queue(dotqApi._taskQueue); return(handle); }