Exemple #1
0
        internal static Task <T> QueueTask <T>(this OrleansTaskScheduler scheduler, Func <Task <T> > taskFunc, ISchedulingContext targetContext)
        {
            var workItem = new AsyncClosureWorkItem <T>(taskFunc);

            scheduler.QueueWorkItem(workItem, targetContext);
            return(workItem.Task);
        }
        public void Sched_AC_Test()
        {
            int n = 0;
            bool insideTask = false;
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();
            orleansTaskScheduler = TestHelper.InitializeSchedulerForTesting(context);

            Console.WriteLine("Running Main in Context=" + RuntimeContext.Current);
            orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() =>
                {
                    for (int i = 0; i < 10; i++)
                    {
                        Task.Factory.StartNew(() => 
                        {
                            // ReSharper disable AccessToModifiedClosure
                            Console.WriteLine("Starting " + i + " in Context=" + RuntimeContext.Current); 
                            Assert.IsFalse(insideTask, "Starting new task when I am already inside task of iteration {0}", n);
                            insideTask = true;
                            int k = n; 
                            Thread.Sleep(100); 
                            n = k + 1;
                            insideTask = false;
                            // ReSharper restore AccessToModifiedClosure
                        }).Ignore();
                    }
                }), context);

            // Pause to let things run
            Thread.Sleep(1500);

            // N should be 10, because all tasks should execute serially
            Assert.IsTrue(n != 0, "Work items did not get executed");
            Assert.AreEqual(10, n, "Work items executed concurrently");
        }
Exemple #3
0
        internal static Task QueueNamedTask(this OrleansTaskScheduler scheduler, Func <Task> taskFunc, ISchedulingContext targetContext, string activityName = null)
        {
            var workItem = new AsyncClosureWorkItem(taskFunc, activityName);

            scheduler.QueueWorkItem(workItem, targetContext);
            return(workItem.Task);
        }
        internal static Task QueueTask(this OrleansTaskScheduler scheduler, Func <Task> taskFunc, IGrainContext targetContext)
        {
            var workItem = new AsyncClosureWorkItem(taskFunc, targetContext);

            scheduler.QueueWorkItem(workItem);
            return(workItem.Task);
        }
Exemple #5
0
        internal static Task QueueAction(this OrleansTaskScheduler scheduler, Action action, ISchedulingContext targetContext)
        {
            var    resolver = new TaskCompletionSource <bool>();
            Action syncFunc =
                () =>
            {
                try
                {
                    action();
                    resolver.TrySetResult(true);
                }
                catch (Exception exc)
                {
                    resolver.TrySetException(exc);
                }
            };

            scheduler.QueueWorkItem(new ClosureWorkItem(() => syncFunc()), targetContext);
            return(resolver.Task);
        }
        internal static Task QueueNamedTask(this OrleansTaskScheduler scheduler, Func <Task> taskFunc, ISchedulingContext targetContext, string activityName = null)
        {
            var         resolver  = new TaskCompletionSource <bool>();
            Func <Task> asyncFunc =
                async() =>
            {
                try
                {
                    await taskFunc();

                    resolver.TrySetResult(true);
                }
                catch (Exception exc)
                {
                    resolver.TrySetException(exc);
                }
            };

            scheduler.QueueWorkItem(new ClosureWorkItem(() => asyncFunc().Ignore(), () => activityName), targetContext);
            return(resolver.Task);
        }
        internal static Task <T> QueueTask <T>(this OrleansTaskScheduler scheduler, Func <Task <T> > taskFunc, ISchedulingContext targetContext)
        {
            var         resolver  = new TaskCompletionSource <T>();
            Func <Task> asyncFunc =
                async() =>
            {
                try
                {
                    T result = await taskFunc();

                    resolver.TrySetResult(result);
                }
                catch (Exception exc)
                {
                    resolver.TrySetException(exc);
                }
            };

            // it appears that it's not important that we fire-and-forget asyncFunc() because we wait on the
            scheduler.QueueWorkItem(new ClosureWorkItem(() => asyncFunc().Ignore()), targetContext);
            return(resolver.Task);
        }
        public async Task Sched_AC_WaitTest()
        {
            int n = 0;
            bool insideTask = false;
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();
            orleansTaskScheduler = TestHelper.InitializeSchedulerForTesting(context);

            var result = new TaskCompletionSource<bool>();

            orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() =>
                {
                    var task1 = Task.Factory.StartNew(() => 
                    {
                        Console.WriteLine("Starting 1"); 
                        Assert.IsFalse(insideTask, "Starting new task when I am already inside task of iteration {0}", n);
                        insideTask = true;
                        Console.WriteLine("===> 1a"); 
                        Thread.Sleep(1000); n = n + 3; 
                        Console.WriteLine("===> 1b");
                        insideTask = false;
                    });
                    var task2 = Task.Factory.StartNew(() =>
                    {
                        Console.WriteLine("Starting 2");
                        Assert.IsFalse(insideTask, "Starting new task when I am alraedy inside task of iteration {0}", n);
                        insideTask = true;
                        Console.WriteLine("===> 2a");
                        task1.Wait();
                        Console.WriteLine("===> 2b");
                        n = n * 5;
                        Console.WriteLine("===> 2c");
                        insideTask = false;
                        result.SetResult(true);
                    });
                    task1.Ignore();
                    task2.Ignore();
                }), context);

            var timeoutLimit = TimeSpan.FromMilliseconds(1500);
            try
            {
                await result.Task.WithTimeout(timeoutLimit);
            }
            catch (TimeoutException)
            {
                Assert.Fail("Result did not arrive before timeout " + timeoutLimit);
            }

            Assert.IsTrue(n != 0, "Work items did not get executed");
            Assert.AreEqual(15, n, "Work items executed out of order");
        }
        public void Sched_Task_JoinAll()
        {
            var result = new TaskCompletionSource<bool>();
            int n = 0;
            Task<int>[] tasks = null;

            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            UnitTestSchedulingContext context = new UnitTestSchedulingContext();
            orleansTaskScheduler = TestHelper.InitializeSchedulerForTesting(context);

            // ReSharper disable AccessToModifiedClosure
            orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() =>
            {
                Task<int> task1 = Task<int>.Factory.StartNew(() => { Console.WriteLine("===> 1a"); Thread.Sleep(OneSecond); n = n + 3; Console.WriteLine("===> 1b"); return 1; });
                Task<int> task2 = Task<int>.Factory.StartNew(() => { Console.WriteLine("===> 2a"); Thread.Sleep(OneSecond); n = n + 3; Console.WriteLine("===> 2b"); return 2; });
                Task<int> task3 = Task<int>.Factory.StartNew(() => { Console.WriteLine("===> 3a"); Thread.Sleep(OneSecond); n = n + 3; Console.WriteLine("===> 3b"); return 3; });
                Task<int> task4 = Task<int>.Factory.StartNew(() => { Console.WriteLine("===> 4a"); Thread.Sleep(OneSecond); n = n + 3; Console.WriteLine("===> 4b"); return 4; });
                tasks = new Task<int>[] {task1, task2, task3, task4};
                result.SetResult(true);
            }),context);
            // ReSharper restore AccessToModifiedClosure
            Assert.IsTrue(result.Task.Wait(TwoSeconds)); // Wait for main (one that creates tasks) work item to finish.

            var promise = Task<int[]>.Factory.ContinueWhenAll(tasks, (res) => 
            {
                List<int> output = new List<int>();
                int taskNum = 1;
                foreach (var t in tasks)
                {
                    Assert.IsTrue(t.IsCompleted, "Sub-Task completed");
                    Assert.IsFalse(t.IsFaulted, "Sub-Task faulted: " + t.Exception);
                    var val = t.Result;
                    Assert.AreEqual(taskNum, val, "Value returned by Task " + taskNum);
                    output.Add(val);
                    taskNum++;
                }
                int[] results = output.ToArray();
                return results;
            });
            bool ok = promise.Wait(TimeSpan.FromSeconds(8));
            if (!ok) throw new TimeoutException();

            Assert.IsTrue(n != 0, "Work items did not get executed");
            Assert.AreEqual(12, n, "Not all work items executed");
            long ms = stopwatch.ElapsedMilliseconds;
            Assert.IsTrue(4000 <= ms && ms <= 5000, "Wait time out of range, expected between 4000 and 5000 milliseconds, was " + ms);
        }
        public void Sched_AC_ContinueWith_1_Test()
        {
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();
            orleansTaskScheduler = TestHelper.InitializeSchedulerForTesting(context);

            var result = new TaskCompletionSource<bool>();
            int n = 0;
            // ReSharper disable AccessToModifiedClosure
            orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() =>
                {
                    Task task1 = Task.Factory.StartNew(() => { Console.WriteLine("===> 1a"); Thread.Sleep(OneSecond); n = n + 3; Console.WriteLine("===> 1b"); });
                    Task task2 = task1.ContinueWith((_) => { n = n * 5; Console.WriteLine("===> 2"); });
                    Task task3 = task2.ContinueWith((_) => { n = n / 5; Console.WriteLine("===> 3"); });
                    Task task4 = task3.ContinueWith((_) => { n = n - 2; Console.WriteLine("===> 4"); result.SetResult(true); });
                    task4.Ignore();
                }), context);
            // ReSharper restore AccessToModifiedClosure

            Assert.IsTrue(result.Task.Wait(TwoSeconds));
            Assert.IsTrue(n != 0, "Work items did not get executed");
            Assert.AreEqual(1, n, "Work items executed out of order");
        }
        public void Sched_AC_Current_TaskScheduler()
        {
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();
            OrleansTaskScheduler orleansTaskScheduler = orleansTaskScheduler = TestHelper.InitializeSchedulerForTesting(context);
            ActivationTaskScheduler activationScheduler = orleansTaskScheduler.GetWorkItemGroup(context).TaskRunner;

            // RuntimeContext.InitializeThread(masterScheduler);

            mainDone = false;

            var result = new TaskCompletionSource<bool>();

            Task wrapper = null;
            Task finalPromise = null;
            orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() =>
            {
                Log(1, "Outer ClosureWorkItem " + Task.CurrentId + " starting");
                Assert.AreEqual(activationScheduler, TaskScheduler.Current, "TaskScheduler.Current #0");

                Log(2, "Starting wrapper Task");
                wrapper = Task.Factory.StartNew(() =>
                {
                    Log(3, "Inside wrapper Task Id=" + Task.CurrentId);
                    Assert.AreEqual(activationScheduler, TaskScheduler.Current, "TaskScheduler.Current #1");

                    Log(4, "Wrapper Task " + Task.CurrentId + " creating AC chain");
                    Task promise1 = Task.Factory.StartNew(() =>
                    {
                        Log(5, "#1 Inside AC Task Id=" + Task.CurrentId);
                        Assert.AreEqual(activationScheduler, TaskScheduler.Current, "TaskScheduler.Current #1");
                        SubProcess1(1);
                    });
                    Task promise2 = promise1.ContinueWith((_) =>
                    {
                        Log(6, "#2 Inside AC Task Id=" + Task.CurrentId);
                        Assert.AreEqual(activationScheduler, TaskScheduler.Current, "TaskScheduler.Current #2");
                        SubProcess1(2);
                    });
                    finalPromise = promise2.ContinueWith((_) =>
                    {
                        Log(7, "#3 Inside final AC Task Id=" + Task.CurrentId);
                        Assert.AreEqual(activationScheduler, TaskScheduler.Current, "TaskScheduler.Current #3");
                        SubProcess1(3);
                        result.SetResult(true);
                    });
                    finalPromise.Ignore();

                    Log(8, "Wrapper Task Id=" + Task.CurrentId + " sleeping");
                    Thread.Sleep(TimeSpan.FromSeconds(1));

                    Log(9, "Wrapper Task Id=" + Task.CurrentId + " finished");
                });

                Log(10, "Outer ClosureWorkItem Task Id=" + Task.CurrentId + " sleeping");
                Thread.Sleep(TimeSpan.FromSeconds(1));
                Log(11, "Outer ClosureWorkItem Task Id=" + Task.CurrentId + " awake");

                Log(12, "Finished Outer TaskWorkItem Task Id=" + wrapper.Id);
                mainDone = true;
            }), context);

            Log(13, "Waiting for ClosureWorkItem to spawn wrapper Task");
            for (int i = 0; i < 5 * waitFactor; i++)
            {
                if (wrapper != null) break;
                Thread.Sleep(TimeSpan.FromSeconds(1).Multiply(waitFactor));
            }
            Assert.IsNotNull(wrapper, "Wrapper Task was not created");

            Log(14, "Waiting for wrapper Task Id=" + wrapper.Id + " to complete");
            bool finished = wrapper.Wait(TimeSpan.FromSeconds(2 * waitFactor));
            Log(15, "Done waiting for wrapper Task Id=" + wrapper.Id + " Finished=" + finished);
            if (!finished) throw new TimeoutException();
            Assert.IsFalse(wrapper.IsFaulted, "Wrapper Task faulted: " + wrapper.Exception);
            Assert.IsTrue(wrapper.IsCompleted, "Wrapper Task should be completed");

            Log(16, "Waiting for TaskWorkItem to complete");
            for (int i = 0; i < 15 * waitFactor; i++)
            {
                if (mainDone) break;
                Thread.Sleep(1000 * waitFactor);
            }
            Log(17, "Done waiting for TaskWorkItem to complete MainDone=" + mainDone);
            Assert.IsTrue(mainDone, "Main Task should be completed");
            Assert.IsNotNull(finalPromise, "AC chain not created");

            Log(18, "Waiting for final AC promise to complete");
            finalPromise.Wait(TimeSpan.FromSeconds(4 * waitFactor));
            Log(19, "Done waiting for final promise");
            Assert.IsFalse(finalPromise.IsFaulted, "Final AC faulted: " + finalPromise.Exception);
            Assert.IsTrue(finalPromise.IsCompleted, "Final AC completed");
            Assert.IsTrue(result.Task.Result, "Timeout-1");

            Assert.AreNotEqual(0, stageNum1, "Work items did not get executed-1");
            Assert.AreEqual(3, stageNum1, "Work items executed out of order-1");
        }
        public async Task Sched_AC_Turn_Execution_Order()
        {
            // Can we add a unit test that basicaly checks that any turn is indeed run till completion before any other turn? 
            // For example, you have a  long running main turn and in the middle it spawns a lot of short CWs (on Done promise) and StartNew. 
            // You test that no CW/StartNew runs until the main turn is fully done. And run in stress.

            UnitTestSchedulingContext context = new UnitTestSchedulingContext();
            orleansTaskScheduler = TestHelper.InitializeSchedulerForTesting(context);

            var result1 = new TaskCompletionSource<bool>();
            var result2 = new TaskCompletionSource<bool>();

            orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() =>
            {
                mainDone = false;
                stageNum1 = stageNum2 = 0;

                Task task1 = Task.Factory.StartNew(() => SubProcess1(11));
                Task task2 = task1.ContinueWith((_) => SubProcess1(12));
                Task task3 = task2.ContinueWith((_) => SubProcess1(13));
                Task task4 = task3.ContinueWith((_) => { SubProcess1(14); result1.SetResult(true); });
                task4.Ignore();

                Task task21 = TaskDone.Done.ContinueWith((_) => SubProcess2(21));
                Task task22 = task21.ContinueWith((_) => { SubProcess2(22); result2.SetResult(true); });
                task22.Ignore();

                Thread.Sleep(TimeSpan.FromSeconds(1));
                mainDone = true;
            }), context);

            try { await result1.Task.WithTimeout(TimeSpan.FromSeconds(3)); }
            catch (TimeoutException) { Assert.Fail("Timeout-1"); }
            try { await result2.Task.WithTimeout(TimeSpan.FromSeconds(3)); }
            catch (TimeoutException) { Assert.Fail("Timeout-2"); }

            Assert.AreNotEqual(0, stageNum1, "Work items did not get executed-1");
            Assert.AreNotEqual(0, stageNum2, "Work items did not get executed-2");
            Assert.AreEqual(14, stageNum1, "Work items executed out of order-1");
            Assert.AreEqual(22, stageNum2, "Work items executed out of order-2");
        }