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); }
/// <summary> /// OUTDATED: binds task and handle directly and starts to listen which means it should be used after task is enqueued. /// If this is used with a task which is not enqueued then it will use resources for a promise which cannot be resolved. /// </summary> /// <param name="task"></param> /// <param name="redis"></param> /// <param name="onResolve"></param> public PromiseTaskResultHandle(ITask task, ConnectionMultiplexer redis, Action <TResult> onResolve = null, bool listenImmediately = false) { // this ctor binds promise and tasks itself var promiseClient = RedisPromiseClientFactory.GetInstance(redis); var promise = promiseClient.CreatePromise(); promise.OnResolve = (o => { string message = (string)o; TResult res = JsonConvert.DeserializeObject <TResult>(message); _onResolve(res); }); _promise = promise; _task = task; //TODO: use listenImmediately; }
public static RedisPromiseClient GetInstance(ConnectionMultiplexer redis) { return(RedisPromiseClientFactory.GetInstance(redis)); }