예제 #1
0
        public void Sched_Task_TplFifoTest_TaskScheduler()
        {
            UnitTestSchedulingContext cntx                = new UnitTestSchedulingContext();
            OrleansTaskScheduler      scheduler           = TestInternalHelper.InitializeSchedulerForTesting(cntx);
            ActivationTaskScheduler   activationScheduler = scheduler.GetWorkItemGroup(cntx).TaskRunner;

            int n = 0;

            // ReSharper disable AccessToModifiedClosure
            Task task1 = new Task(() => { Thread.Sleep(1000); n = n + 5; });
            Task task2 = new Task(() => { n = n * 3; });

            // ReSharper restore AccessToModifiedClosure

            // By queuuing to ActivationTaskScheduler we guarantee single threaded ordered execution.
            // If we queued to OrleansTaskScheduler we would not guarantee that.
            task1.Start(activationScheduler);
            task2.Start(activationScheduler);

            // Pause to let things run
            Thread.Sleep(TimeSpan.FromSeconds(2));

            // N should be 15, because the two tasks should execute in order
            Assert.True(n != 0, "Work items did not get executed");
            Assert.Equal(15, n);
        }
        public void Sched_AC_ContinueWith_1_Test()
        {
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();

            this.orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.loggerFactory);

            var result = new TaskCompletionSource <bool>();
            int n      = 0;

            // ReSharper disable AccessToModifiedClosure
            this.orleansTaskScheduler.QueueAction(() =>
            {
                Task task1 = Task.Factory.StartNew(() => { this.output.WriteLine("===> 1a"); Thread.Sleep(OneSecond); n = n + 3; this.output.WriteLine("===> 1b"); });
                Task task2 = task1.ContinueWith((_) => { n = n * 5; this.output.WriteLine("===> 2"); });
                Task task3 = task2.ContinueWith((_) => { n = n / 5; this.output.WriteLine("===> 3"); });
                Task task4 = task3.ContinueWith((_) => { n = n - 2; this.output.WriteLine("===> 4"); result.SetResult(true); });
                task4.Ignore();
            },
                                                  context);
            // ReSharper restore AccessToModifiedClosure

            Assert.True(result.Task.Wait(TwoSeconds));
            Assert.True(n != 0, "Work items did not get executed");
            Assert.Equal(1, n);   // "Work items executed out of order"
        }
        public async Task Sched_Task_SubTaskExecutionSequencing()
        {
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();

            this.scheduler.RegisterWorkContext(context);

            LogContext("Main-task " + Task.CurrentId);

            int n = 0;
            TaskCompletionSource <int> finished = new TaskCompletionSource <int>();
            var    numCompleted = new[] { 0 };
            Action closure      = () =>
            {
                LogContext("ClosureWorkItem-task " + Task.CurrentId);

                for (int i = 0; i < 10; i++)
                {
                    int    id     = -1;
                    Action action = () =>
                    {
                        id = Task.CurrentId.HasValue ? (int)Task.CurrentId : -1;

                        // ReSharper disable AccessToModifiedClosure
                        LogContext("Sub-task " + id + " n=" + n);

                        int k = n;
                        this.output.WriteLine("Sub-task " + id + " sleeping");
                        Thread.Sleep(100);
                        this.output.WriteLine("Sub-task " + id + " awake");
                        n = k + 1;
                        // ReSharper restore AccessToModifiedClosure
                    };
                    Task.Factory.StartNew(action).ContinueWith(tsk =>
                    {
                        LogContext("Sub-task " + id + "-ContinueWith");

                        this.output.WriteLine("Sub-task " + id + " Done");
                        if (Interlocked.Increment(ref numCompleted[0]) == 10)
                        {
                            finished.SetResult(0);
                        }
                    });
                }
            };

            IWorkItem workItem = new ClosureWorkItem(closure);

            this.scheduler.QueueWorkItem(workItem, context);

            // Pause to let things run
            this.output.WriteLine("Main-task sleeping");
            await Task.WhenAny(Task.Delay(TimeSpan.FromSeconds(10)), finished.Task);

            this.output.WriteLine("Main-task awake");

            // N should be 10, because all tasks should execute serially
            Assert.True(n != 0, "Work items did not get executed");
            Assert.Equal(10, n);  // "Work items executed concurrently"
            this.scheduler.Stop();
        }
예제 #4
0
        public void Sched_Task_NewTask_ContinueWith_TaskScheduler()
        {
            UnitTestSchedulingContext rootContext = new UnitTestSchedulingContext();
            OrleansTaskScheduler      scheduler   = TestInternalHelper.InitializeSchedulerForTesting(rootContext);

            output.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                             SynchronizationContext.Current, TaskScheduler.Current);

            Task t0 = new Task(() =>
            {
                output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                                 SynchronizationContext.Current, TaskScheduler.Current);
                Assert.Equal(scheduler, TaskScheduler.Current);  // "TaskScheduler.Current #1"
            });
            Task t1 = t0.ContinueWith(task =>
            {
                Assert.False(task.IsFaulted, "Task #1 Faulted=" + task.Exception);

                output.WriteLine("#2 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                                 SynchronizationContext.Current, TaskScheduler.Current);
                Assert.Equal(scheduler, TaskScheduler.Current);  // "TaskScheduler.Current #2"
            }, scheduler);

            t0.Start(scheduler);
            bool ok = t1.Wait(TimeSpan.FromSeconds(30));

            if (!ok)
            {
                throw new TimeoutException();
            }
        }
        public void Sched_AC_Test()
        {
            int  n          = 0;
            bool insideTask = false;
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();

            orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics);

            output.WriteLine("Running Main in Context=" + RuntimeContext.Current);
            orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() =>
            {
                for (int i = 0; i < 10; i++)
                {
                    Task.Factory.StartNew(() =>
                    {
                        // ReSharper disable AccessToModifiedClosure
                        output.WriteLine("Starting " + i + " in Context=" + RuntimeContext.Current);
                        Assert.False(insideTask, $"Starting new task when I am already inside task of iteration {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.True(n != 0, "Work items did not get executed");
            Assert.Equal(10, n);   // "Work items executed concurrently"
        }
 public OrleansTaskSchedulerAdvancedTests_Set2(ITestOutputHelper output)
 {
     this.output = output;
     OrleansTaskSchedulerBasicTests.InitSchedulerLogging();
     context         = new UnitTestSchedulingContext();
     masterScheduler = TestInternalHelper.InitializeSchedulerForTesting(context);
 }
예제 #7
0
 public OrleansTaskSchedulerAdvancedTests_Set2(ITestOutputHelper output)
 {
     this.output             = output;
     this.loggerFactory      = OrleansTaskSchedulerBasicTests.InitSchedulerLogging();
     this.context            = new UnitTestSchedulingContext();
     this.performanceMetrics = new TestHooksHostEnvironmentStatistics();
 }
예제 #8
0
        public void Sched_Task_StartNew_ContinueWith_TaskScheduler()
        {
            UnitTestSchedulingContext rootContext = new UnitTestSchedulingContext();
            OrleansTaskScheduler      scheduler   = TestInternalHelper.InitializeSchedulerForTesting(rootContext);

            output.WriteLine("#0 - StartNew - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                             SynchronizationContext.Current, TaskScheduler.Current);

            Task t0 = Task.Factory.StartNew(state =>
            {
                output.WriteLine("#1 - StartNew - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                                 SynchronizationContext.Current, TaskScheduler.Current);
                Assert.Equal(scheduler, TaskScheduler.Current);  // "TaskScheduler.Current #1"
            }, null, CancellationToken.None, TaskCreationOptions.None, scheduler);
            Task t1 = t0.ContinueWith(task =>
            {
                Assert.False(task.IsFaulted, "Task #1 Faulted=" + task.Exception);

                output.WriteLine("#2 - StartNew - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                                 SynchronizationContext.Current, TaskScheduler.Current);
                Assert.Equal(scheduler, TaskScheduler.Current);  // "TaskScheduler.Current #2"
            }, scheduler);
            bool ok = t1.Wait(TimeSpan.FromSeconds(30));

            if (!ok)
            {
                throw new TimeoutException();
            }
        }
        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");
        }
        public void Sched_Task_TplFifoTest()
        {
            // This is not a great test because there's a 50/50 shot that it will work even if the scheduling
            // is completely and thoroughly broken and both closures are executed "simultaneously"
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();
            OrleansTaskScheduler      orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context);
            ActivationTaskScheduler   scheduler            = orleansTaskScheduler.GetWorkItemGroup(context).TaskRunner;

            int n = 0;

            // ReSharper disable AccessToModifiedClosure
            Task task1 = new Task(() => { Thread.Sleep(1000); n = n + 5; });
            Task task2 = new Task(() => { n = n * 3; });

            // ReSharper restore AccessToModifiedClosure

            task1.Start(scheduler);
            task2.Start(scheduler);

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

            // N should be 15, because the two tasks should execute in order
            Assert.IsTrue(n != 0, "Work items did not get executed");
            Assert.AreEqual(15, n, "Work items executed out of order");
            output.WriteLine("Test executed OK.");
            orleansTaskScheduler.Stop();
        }
 public OrleansTaskSchedulerAdvancedTests_Set2(ITestOutputHelper output)
 {
     this.output = output;
     OrleansTaskSchedulerBasicTests.InitSchedulerLogging();
     context = new UnitTestSchedulingContext();
     masterScheduler = TestInternalHelper.InitializeSchedulerForTesting(context);
 }
예제 #12
0
        public void Sched_Task_StartTask_Wait_Wrapped()
        {
            UnitTestSchedulingContext cntx      = new UnitTestSchedulingContext();
            OrleansTaskScheduler      scheduler = TestInternalHelper.InitializeSchedulerForTesting(cntx);

            const int NumTasks = 100;

            ManualResetEvent[] flags = new ManualResetEvent[NumTasks];
            for (int i = 0; i < NumTasks; i++)
            {
                flags[i] = new ManualResetEvent(false);
            }

            Task[] tasks = new Task[NumTasks];
            for (int i = 0; i < NumTasks; i++)
            {
                int taskNum = i; // Capture
                tasks[i] = new Task(() => { output.WriteLine("Inside Task-" + taskNum); flags[taskNum].WaitOne(); });
                output.WriteLine("Created Task-" + taskNum + " Id=" + tasks[taskNum].Id);
            }

            Task[] wrappers = new Task[NumTasks];
            for (int i = 0; i < NumTasks; i++)
            {
                int taskNum = i; // Capture
                wrappers[i] = new Task(() =>
                {
                    output.WriteLine("Inside Wrapper-" + taskNum);
                    tasks[taskNum].Start(scheduler);
                });
                wrappers[i].ContinueWith(t =>
                {
                    Assert.False(t.IsFaulted, "Warpper.IsFaulted-" + taskNum + " " + t.Exception);
                    Assert.True(t.IsCompleted, "Wrapper.IsCompleted-" + taskNum);
                });
                output.WriteLine("Created Wrapper-" + taskNum + " Task.Id=" + wrappers[taskNum].Id);
            }

            foreach (var wrapper in wrappers)
            {
                wrapper.Start(scheduler);
            }
            foreach (var flag in flags)
            {
                flag.Set();
            }
            for (int i = 0; i < wrappers.Length; i++)
            {
                bool ok = wrappers[i].Wait(TimeSpan.FromMilliseconds(NumTasks * 150 * 2));
                Assert.True(ok, "Wait completed successfully for Wrapper-" + i);
            }

            for (int i = 0; i < tasks.Length; i++)
            {
                bool ok = tasks[i].Wait(TimeSpan.FromMilliseconds(NumTasks * 150 * 2));
                Assert.True(ok, "Wait completed successfully for Task-" + i);
                Assert.False(tasks[i].IsFaulted, "Task.IsFaulted-" + i + " " + tasks[i].Exception);
                Assert.True(tasks[i].IsCompleted, "Task.IsCompleted-" + i);
            }
        }
예제 #13
0
        public void Sched_Task_StartTask_2()
        {
            UnitTestSchedulingContext cntx      = new UnitTestSchedulingContext();
            OrleansTaskScheduler      scheduler = TestInternalHelper.InitializeSchedulerForTesting(cntx);

            ManualResetEvent pause1 = new ManualResetEvent(false);
            ManualResetEvent pause2 = new ManualResetEvent(false);
            Task             task1  = new Task(() => { pause1.WaitOne(); output.WriteLine("Task-1"); });
            Task             task2  = new Task(() => { pause2.WaitOne(); output.WriteLine("Task-2"); });

            pause1.Set();
            task1.Start(scheduler);

            bool ok = task1.Wait(TimeSpan.FromMilliseconds(100));

            if (!ok)
            {
                throw new TimeoutException();
            }

            Assert.True(task1.IsCompleted, "Task.IsCompleted-1");
            Assert.False(task1.IsFaulted, "Task.IsFaulted-1");

            task2.Start(scheduler);
            pause2.Set();
            ok = task2.Wait(TimeSpan.FromMilliseconds(100));
            if (!ok)
            {
                throw new TimeoutException();
            }

            Assert.True(task2.IsCompleted, "Task.IsCompleted-2");
            Assert.False(task2.IsFaulted, "Task.IsFaulted-2");
        }
        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();

            this.orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.loggerFactory);

            // ReSharper disable AccessToModifiedClosure
            this.orleansTaskScheduler.QueueAction(() =>
            {
                Task <int> task1 = Task <int> .Factory.StartNew(() => { this.output.WriteLine("===> 1a"); Thread.Sleep(OneSecond); n = n + 3; this.output.WriteLine("===> 1b"); return(1); });
                Task <int> task2 = Task <int> .Factory.StartNew(() => { this.output.WriteLine("===> 2a"); Thread.Sleep(OneSecond); n = n + 3; this.output.WriteLine("===> 2b"); return(2); });
                Task <int> task3 = Task <int> .Factory.StartNew(() => { this.output.WriteLine("===> 3a"); Thread.Sleep(OneSecond); n = n + 3; this.output.WriteLine("===> 3b"); return(3); });
                Task <int> task4 = Task <int> .Factory.StartNew(() => { this.output.WriteLine("===> 4a"); Thread.Sleep(OneSecond); n = n + 3; this.output.WriteLine("===> 4b"); return(4); });
                tasks            = new Task <int>[] { task1, task2, task3, task4 };
                result.SetResult(true);
            },
                                                  context);
            // ReSharper restore AccessToModifiedClosure
            Assert.True(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.True(t.IsCompleted, "Sub-Task completed");
                    Assert.False(t.IsFaulted, "Sub-Task faulted: " + t.Exception);
                    var val = t.Result;
                    Assert.Equal(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.True(n != 0, "Work items did not get executed");
            Assert.Equal(12, n);   // "Not all work items executed"
            long ms = stopwatch.ElapsedMilliseconds;

            Assert.True(4000 <= ms && ms <= 5000, "Wait time out of range, expected between 4000 and 5000 milliseconds, was " + ms);
        }
 public OrleansTaskSchedulerAdvancedTests_Set2(ITestOutputHelper output)
 {
     this.output             = output;
     loggerFactory           = OrleansTaskSchedulerBasicTests.InitSchedulerLogging();
     context                 = new UnitTestSchedulingContext();
     this.performanceMetrics = new SiloPerformanceMetrics(new NoOpHostEnvironmentStatistics(loggerFactory), new AppEnvironmentStatistics(), this.loggerFactory);
     masterScheduler         = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, loggerFactory);
 }
예제 #16
0
        public async Task OrleansSched_Test1_Bounce()
        {
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();
            OrleansTaskScheduler      orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context);
            ActivationTaskScheduler   scheduler            = orleansTaskScheduler.GetWorkItemGroup(context).TaskRunner;

            await Run_ActivationSched_Test1(scheduler, true);
        }
예제 #17
0
 public OrleansTaskSchedulerBasicTests(ITestOutputHelper output)
 {
     this.output = output;
     SynchronizationContext.SetSynchronizationContext(null);
     this.loggerFactory = InitSchedulerLogging();
     this.rootContext   = new UnitTestSchedulingContext();
     this.scheduler     = TestInternalHelper.InitializeSchedulerForTesting(this.rootContext, this.loggerFactory);
 }
예제 #18
0
        public async Task OrleansSched_Test1()
        {
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();
            OrleansTaskScheduler      orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.loggerFactory);
            ActivationTaskScheduler   scheduler            = orleansTaskScheduler.GetWorkItemGroup(context).TaskScheduler;

            await Run_ActivationSched_Test1(scheduler, false);
        }
 public OrleansTaskSchedulerBasicTests(ITestOutputHelper output)
 {
     this.output = output;
     SynchronizationContext.SetSynchronizationContext(null);
     this.loggerFactory    = InitSchedulerLogging();
     this.rootContext      = new UnitTestSchedulingContext();
     rootContext.Scheduler = SchedulingHelper.CreateWorkItemGroupForTesting(this.rootContext, this.loggerFactory);
 }
예제 #20
0
 public OrleansTaskSchedulerBasicTests(ITestOutputHelper output)
 {
     this.output = output;
     SynchronizationContext.SetSynchronizationContext(null);
     this.loggerFactory      = InitSchedulerLogging();
     this.performanceMetrics = new SiloPerformanceMetrics(new NoOpHostEnvironmentStatistics(this.loggerFactory), new AppEnvironmentStatistics(), this.loggerFactory, Options.Create <LoadSheddingOptions>(new LoadSheddingOptions()));
     this.rootContext        = new UnitTestSchedulingContext();
     this.scheduler          = TestInternalHelper.InitializeSchedulerForTesting(this.rootContext, this.performanceMetrics, this.loggerFactory);
 }
예제 #21
0
 public OrleansTaskSchedulerBasicTests(ITestOutputHelper output)
 {
     this.output = output;
     SynchronizationContext.SetSynchronizationContext(null);
     this.loggerFactory      = InitSchedulerLogging();
     this.performanceMetrics = new TestHooksHostEnvironmentStatistics();
     this.rootContext        = new UnitTestSchedulingContext();
     this.scheduler          = TestInternalHelper.InitializeSchedulerForTesting(this.rootContext, this.performanceMetrics, this.loggerFactory);
 }
예제 #22
0
        public async Task OrleansSched_Test1_Bounce()
        {
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();

            using var workItemGroup = SchedulingHelper.CreateWorkItemGroupForTesting(context, this.loggerFactory);
            ActivationTaskScheduler scheduler = workItemGroup.TaskScheduler;

            await Run_ActivationSched_Test1(scheduler, true);
        }
 public OrleansTaskSchedulerAdvancedTests_Set2(ITestOutputHelper output)
 {
     this.output   = output;
     loggerFactory = OrleansTaskSchedulerBasicTests.InitSchedulerLogging();
     context       = new UnitTestSchedulingContext();
     this.runtimeStatisticsGroup = new RuntimeStatisticsGroup(loggerFactory);
     this.performanceMetrics     = new SiloPerformanceMetrics(this.runtimeStatisticsGroup, this.loggerFactory);
     masterScheduler             = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, loggerFactory);
 }
예제 #24
0
        public void Sched_Task_SubTaskExecutionSequencing()
        {
            UnitTestSchedulingContext rootContext = new UnitTestSchedulingContext();
            OrleansTaskScheduler      scheduler   = TestInternalHelper.InitializeSchedulerForTesting(rootContext);

            UnitTestSchedulingContext context = new UnitTestSchedulingContext();

            scheduler.RegisterWorkContext(context);

            LogContext("Main-task " + Task.CurrentId);

            int n = 0;

            Action closure = () =>
            {
                LogContext("ClosureWorkItem-task " + Task.CurrentId);

                for (int i = 0; i < 10; i++)
                {
                    int    id     = -1;
                    Action action = () =>
                    {
                        id = Task.CurrentId.HasValue ? (int)Task.CurrentId : -1;

                        // ReSharper disable AccessToModifiedClosure
                        LogContext("Sub-task " + id + " n=" + n);

                        int k = n;
                        Console.WriteLine("Sub-task " + id + " sleeping");
                        Thread.Sleep(100);
                        Console.WriteLine("Sub-task " + id + " awake");
                        n = k + 1;
                        // ReSharper restore AccessToModifiedClosure
                    };
                    Task.Factory.StartNew(action).ContinueWith(tsk =>
                    {
                        LogContext("Sub-task " + id + "-ContinueWith");

                        Console.WriteLine("Sub-task " + id + " Done");
                    });
                }
            };

            IWorkItem workItem = new ClosureWorkItem(closure);

            scheduler.QueueWorkItem(workItem, context);

            // Pause to let things run
            Console.WriteLine("Main-task sleeping");
            Thread.Sleep(TimeSpan.FromSeconds(2));
            Console.WriteLine("Main-task awake");

            // 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");
            scheduler.Stop();
        }
예제 #25
0
 public OrleansTaskSchedulerBasicTests(ITestOutputHelper output)
 {
     this.output = output;
     SynchronizationContext.SetSynchronizationContext(null);
     loggerFactory = InitSchedulerLogging();
     this.runtimeStatisticsGroup = new RuntimeStatisticsGroup(loggerFactory);
     this.performanceMetrics     = new SiloPerformanceMetrics(this.runtimeStatisticsGroup, this.loggerFactory);
     this.rootContext            = new UnitTestSchedulingContext();
     this.scheduler = TestInternalHelper.InitializeSchedulerForTesting(rootContext, this.performanceMetrics, loggerFactory);
 }
        public void Sched_AC_ContinueWith_2_OrleansSched()
        {
            var context = new UnitTestSchedulingContext();

            using var workItemGroup = SchedulingHelper.CreateWorkItemGroupForTesting(context, loggerFactory);
            context.Scheduler       = workItemGroup;

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

            Task task1 = Task.Factory.StartNew(
                () => { this.output.WriteLine("===> 1a"); Thread.Sleep(OneSecond); throw new ArgumentException(); },
                CancellationToken.None,
                TaskCreationOptions.RunContinuationsAsynchronously,
                workItemGroup.TaskScheduler);

            Task task2 = task1.ContinueWith((Task t) =>
            {
                if (!t.IsFaulted)
                {
                    this.output.WriteLine("===> 2");
                }
                else
                {
                    this.output.WriteLine("===> 3");
                    failed1 = true;
                    result1.SetResult(true);
                }
            },
                                            workItemGroup.TaskScheduler);
            Task task3 = task1.ContinueWith((Task t) =>
            {
                if (!t.IsFaulted)
                {
                    this.output.WriteLine("===> 4");
                }
                else
                {
                    this.output.WriteLine("===> 5");
                    failed2 = true;
                    result2.SetResult(true);
                }
            },
                                            workItemGroup.TaskScheduler);

            task1.Ignore();
            task2.Ignore();
            task3.Ignore();
            Assert.True(result1.Task.Wait(TwoSeconds), "First ContinueWith did not fire.");
            Assert.True(result2.Task.Wait(TwoSeconds), "Second ContinueWith did not fire.");
            Assert.True(failed1);  // "First ContinueWith did not fire error handler."
            Assert.True(failed2);  // "Second ContinueWith did not fire error handler."
        }
예제 #27
0
        public async Task Sched_Stopped_WorkItemGroup()
        {
            var           context       = new UnitTestSchedulingContext();
            var           scheduler     = this.orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.loggerFactory);
            WorkItemGroup workItemGroup = this.orleansTaskScheduler.GetWorkItemGroup(context);

            void CheckScheduler(object state)
            {
                Assert.IsType <string>(state);
                Assert.Equal("some state", state as string);
                Assert.IsType <ActivationTaskScheduler>(TaskScheduler.Current);
            }

            Task <Task> ScheduleTask() => Task.Factory.StartNew(
                state =>
            {
                CheckScheduler(state);

                return(Task.Factory.StartNew(
                           async s =>
                {
                    CheckScheduler(s);
                    await Task.Delay(50);
                    CheckScheduler(s);
                },
                           state).Unwrap());
            },
                "some state",
                CancellationToken.None,
                TaskCreationOptions.DenyChildAttach,
                workItemGroup.TaskScheduler);

            // Check that the WorkItemGroup is functioning.
            await await ScheduleTask();

            workItemGroup.Stop();

            var taskAfterStopped = ScheduleTask();
            var resultTask       = await Task.WhenAny(taskAfterStopped, Task.Delay(TimeSpan.FromSeconds(10)));

            Assert.Same(taskAfterStopped, resultTask);

            await await taskAfterStopped;

            // Wait for the WorkItemGroup to upgrade the warning to an error and try again.
            // This delay is based upon SchedulingOptions.StoppedActivationWarningInterval.
            await Task.Delay(TimeSpan.FromMilliseconds(300));

            taskAfterStopped = ScheduleTask();
            resultTask       = await Task.WhenAny(taskAfterStopped, Task.Delay(TimeSpan.FromSeconds(10)));

            Assert.Same(taskAfterStopped, resultTask);

            await await taskAfterStopped;
        }
        public async Task Sched_AC_WaitTest()
        {
            int  n          = 0;
            bool insideTask = false;
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();

            this.orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.loggerFactory);

            var result = new TaskCompletionSource <bool>();

            this.orleansTaskScheduler.QueueAction(() =>
            {
                var task1 = Task.Factory.StartNew(() =>
                {
                    this.output.WriteLine("Starting 1");
                    Assert.False(insideTask, $"Starting new task when I am already inside task of iteration {n}");
                    insideTask = true;
                    this.output.WriteLine("===> 1a");
                    Thread.Sleep(1000); n = n + 3;
                    this.output.WriteLine("===> 1b");
                    insideTask = false;
                });
                var task2 = Task.Factory.StartNew(() =>
                {
                    this.output.WriteLine("Starting 2");
                    Assert.False(insideTask, $"Starting new task when I am already inside task of iteration {n}");
                    insideTask = true;
                    this.output.WriteLine("===> 2a");
                    task1.Wait();
                    this.output.WriteLine("===> 2b");
                    n = n * 5;
                    this.output.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.True(false, "Result did not arrive before timeout " + timeoutLimit);
            }

            Assert.True(n != 0, "Work items did not get executed");
            Assert.Equal(15, n);   // "Work items executed out of order"
        }
예제 #29
0
        public void Sched_Task_ClosureWorkItem_Wait()
        {
            UnitTestSchedulingContext cntx      = new UnitTestSchedulingContext();
            OrleansTaskScheduler      scheduler = TestInternalHelper.InitializeSchedulerForTesting(cntx);

            const int NumTasks = 10;

            ManualResetEvent[] flags = new ManualResetEvent[NumTasks];
            for (int i = 0; i < NumTasks; i++)
            {
                flags[i] = new ManualResetEvent(false);
            }

            Task[] tasks = new Task[NumTasks];
            for (int i = 0; i < NumTasks; i++)
            {
                int taskNum = i; // Capture
                tasks[i] = new Task(() => { Console.WriteLine("Inside Task-" + taskNum); flags[taskNum].WaitOne(); });
            }

            ClosureWorkItem[] workItems = new ClosureWorkItem[NumTasks];
            for (int i = 0; i < NumTasks; i++)
            {
                int taskNum = i; // Capture
                workItems[i] = new ClosureWorkItem(() =>
                {
                    Console.WriteLine("Inside ClosureWorkItem-" + taskNum);
                    tasks[taskNum].Start(scheduler);
                    bool ok = tasks[taskNum].Wait(TimeSpan.FromMilliseconds(NumTasks * 100));
                    Assert.IsTrue(ok, "Wait completed successfully inside ClosureWorkItem-" + taskNum);
                });
            }

            foreach (var workItem in workItems)
            {
                scheduler.QueueWorkItem(workItem, cntx);
            }
            foreach (var flag in flags)
            {
                flag.Set();
            }
            for (int i = 0; i < tasks.Length; i++)
            {
                bool ok = tasks[i].Wait(TimeSpan.FromMilliseconds(NumTasks * 150));
                Assert.IsTrue(ok, "Wait completed successfully for Task-" + i);
            }


            for (int i = 0; i < tasks.Length; i++)
            {
                Assert.IsFalse(tasks[i].IsFaulted, "Task.IsFaulted-" + i + " Exception=" + tasks[i].Exception);
                Assert.IsTrue(tasks[i].IsCompleted, "Task.IsCompleted-" + i);
            }
        }
예제 #30
0
        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");
        }
예제 #31
0
        public void Sched_Task_RequestContext_NewTask_ContinueWith()
        {
            UnitTestSchedulingContext rootContext = new UnitTestSchedulingContext();
            OrleansTaskScheduler      scheduler   = TestInternalHelper.InitializeSchedulerForTesting(rootContext);

            const string key = "K";
            int          val = TestConstants.random.Next();

            RequestContext.Set(key, val);

            Console.WriteLine("Initial - SynchronizationContext.Current={0} TaskScheduler.Current={1} Thread={2}",
                              SynchronizationContext.Current, TaskScheduler.Current, Thread.CurrentThread.ManagedThreadId);

            Assert.AreEqual(val, RequestContext.Get(key), "RequestContext.Get Initial");

            Task t0 = new Task(() =>
            {
                Console.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1} Thread={2}",
                                  SynchronizationContext.Current, TaskScheduler.Current, Thread.CurrentThread.ManagedThreadId);

                Assert.AreEqual(val, RequestContext.Get(key), "RequestContext.Get #0");

                Task t1 = new Task(() =>
                {
                    Console.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1} Thread={2}",
                                      SynchronizationContext.Current, TaskScheduler.Current, Thread.CurrentThread.ManagedThreadId);
                    Assert.AreEqual(val, RequestContext.Get(key), "RequestContext.Get #1");
                });
                Task t2 = t1.ContinueWith(task =>
                {
                    Assert.IsFalse(task.IsFaulted, "Task #1 FAULTED=" + task.Exception);

                    Console.WriteLine("#2 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1} Thread={2}",
                                      SynchronizationContext.Current, TaskScheduler.Current, Thread.CurrentThread.ManagedThreadId);
                    Assert.AreEqual(val, RequestContext.Get(key), "RequestContext.Get #2");
                });
                t1.Start(scheduler);
                bool ok = t2.Wait(TimeSpan.FromSeconds(5));
                if (!ok)
                {
                    throw new TimeoutException();
                }
            });

            t0.Start(scheduler);
            bool finished = t0.Wait(TimeSpan.FromSeconds(10));

            if (!finished)
            {
                throw new TimeoutException();
            }
            Assert.IsFalse(t0.IsFaulted, "Task #0 FAULTED=" + t0.Exception);
        }
        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");
        }
예제 #33
0
        public void Sched_Task_ClosureWorkItem_SpecificScheduler()
        {
            UnitTestSchedulingContext context             = new UnitTestSchedulingContext();
            OrleansTaskScheduler      scheduler           = TestInternalHelper.InitializeSchedulerForTesting(context);
            ActivationTaskScheduler   activationScheduler = scheduler.GetWorkItemGroup(context).TaskRunner;

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

            Task t1 = null;

            scheduler.QueueWorkItem(new ClosureWorkItem(() =>
            {
                try
                {
                    Console.WriteLine("#0 - TaskWorkItem - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                                      SynchronizationContext.Current, TaskScheduler.Current);
                    Assert.AreEqual(activationScheduler, TaskScheduler.Current, "TaskScheduler.Current #0");

                    t1 = new Task(() =>
                    {
                        Console.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                                          SynchronizationContext.Current, TaskScheduler.Current);
                        Assert.AreEqual(scheduler, TaskScheduler.Current, "TaskScheduler.Current #1");
                        result1.SetResult(true);
                    });
                    t1.Start(scheduler);

                    result0.SetResult(true);
                }
                catch (Exception exc)
                {
                    result0.SetException(exc);
                }
            }), context);

            result0.Task.Wait(TimeSpan.FromSeconds(1));
            Assert.IsTrue(result0.Task.Exception == null, "Task-0 should not throw exception: " + result0.Task.Exception);
            Assert.IsTrue(result0.Task.Result, "Task-0 completed");

            Assert.IsNotNull(t1, "Task-1 started");
            result1.Task.Wait(TimeSpan.FromSeconds(1));
            Assert.IsTrue(t1.IsCompleted, "Task-1 completed");
            Assert.IsFalse(t1.IsFaulted, "Task-1 faulted: " + t1.Exception);
            Assert.IsTrue(result1.Task.Result, "Task-1 completed");
        }
        public void Async_Task_Start_OrleansTaskScheduler()
        {
            InitSchedulerLogging();
            UnitTestSchedulingContext cntx = new UnitTestSchedulingContext();
            OrleansTaskScheduler scheduler = TestInternalHelper.InitializeSchedulerForTesting(cntx);

            int expected = 2;
            bool done = false;
            Task<int> t = new Task<int>(() => { done = true; return expected; });
            t.Start(scheduler);

            int received = t.Result;
            Assert.True(t.IsCompleted, "Task should have completed");
            Assert.False(t.IsFaulted, "Task should not thrown exception: " + t.Exception);
            Assert.True(done, "Task should be done");
            Assert.Equal(expected, received);      
        }
        public void Async_Task_Start_ActivationTaskScheduler()
        {
            InitSchedulerLogging();
            UnitTestSchedulingContext cntx = new UnitTestSchedulingContext();
            OrleansTaskScheduler masterScheduler = TestInternalHelper.InitializeSchedulerForTesting(cntx);
            ActivationTaskScheduler activationScheduler = masterScheduler.GetWorkItemGroup(cntx).TaskRunner;

            int expected = 2;
            bool done = false;
            Task<int> t = new Task<int>(() => { done = true; return expected; });
            t.Start(activationScheduler);

            int received = t.Result;
            Assert.IsTrue(t.IsCompleted, "Task should have completed");
            Assert.IsFalse(t.IsFaulted, "Task should not thrown exception: " + t.Exception);
            Assert.IsTrue(done, "Task should be done");
            Assert.AreEqual(expected, received, "Task did not return expected value " + expected);
        }
        public void Sched_Task_StartNew_ContinueWith_TaskScheduler()
        {
            UnitTestSchedulingContext rootContext = new UnitTestSchedulingContext();
            OrleansTaskScheduler scheduler = TestInternalHelper.InitializeSchedulerForTesting(rootContext);

            output.WriteLine("#0 - StartNew - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                SynchronizationContext.Current, TaskScheduler.Current);

            Task t0 = Task.Factory.StartNew(state =>
            {
                output.WriteLine("#1 - StartNew - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                    SynchronizationContext.Current, TaskScheduler.Current);
                Assert.Equal(scheduler, TaskScheduler.Current);  // "TaskScheduler.Current #1"
            }, null, CancellationToken.None, TaskCreationOptions.None, scheduler);
            Task t1 = t0.ContinueWith(task =>
            {
                Assert.False(task.IsFaulted, "Task #1 Faulted=" + task.Exception);

                output.WriteLine("#2 - StartNew - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                    SynchronizationContext.Current, TaskScheduler.Current);
                Assert.Equal(scheduler, TaskScheduler.Current);  // "TaskScheduler.Current #2"
            }, scheduler);
            bool ok = t1.Wait(TimeSpan.FromSeconds(30));
            if (!ok) throw new TimeoutException();
        }
        public void Sched_Task_NewTask_ContinueWith_TaskScheduler()
        {
            UnitTestSchedulingContext rootContext = new UnitTestSchedulingContext();
            OrleansTaskScheduler scheduler = TestInternalHelper.InitializeSchedulerForTesting(rootContext);

            output.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                SynchronizationContext.Current, TaskScheduler.Current);

            Task t0 = new Task(() =>
            {
                output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", 
                    SynchronizationContext.Current, TaskScheduler.Current);
                Assert.Equal(scheduler, TaskScheduler.Current);  // "TaskScheduler.Current #1"
            });
            Task t1 = t0.ContinueWith(task =>
            {
                Assert.False(task.IsFaulted, "Task #1 Faulted=" + task.Exception);

                output.WriteLine("#2 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                    SynchronizationContext.Current, TaskScheduler.Current);
                Assert.Equal(scheduler, TaskScheduler.Current);  // "TaskScheduler.Current #2"
            }, scheduler);
            t0.Start(scheduler);
            bool ok = t1.Wait(TimeSpan.FromSeconds(30));
            if (!ok) throw new TimeoutException();
        }
        public void Sched_Task_StartTask_1()
        {
            UnitTestSchedulingContext cntx = new UnitTestSchedulingContext();;
            OrleansTaskScheduler scheduler = TestHelper.InitializeSchedulerForTesting(cntx);

            ManualResetEvent pause1 = new ManualResetEvent(false);
            ManualResetEvent pause2 = new ManualResetEvent(false);
            Task task1 = new Task(() => { pause1.WaitOne(); Console.WriteLine("Task-1"); });
            Task task2 = new Task(() => { pause2.WaitOne(); Console.WriteLine("Task-2"); });

            task1.Start(scheduler);
            task2.Start(scheduler);

            pause1.Set();
            bool ok = task1.Wait(TimeSpan.FromMilliseconds(100));
            if (!ok) throw new TimeoutException();
            Assert.IsTrue(task1.IsCompleted, "Task.IsCompleted-1");
            Assert.IsFalse(task1.IsFaulted, "Task.IsFaulted-1");

            pause2.Set();
            ok = task2.Wait(TimeSpan.FromMilliseconds(100));
            if (!ok) throw new TimeoutException();
            Assert.IsTrue(task2.IsCompleted, "Task.IsCompleted-2");
            Assert.IsFalse(task2.IsFaulted, "Task.IsFaulted-2");
        }
        public void Sched_Task_TplFifoTest()
        {
            // This is not a great test because there's a 50/50 shot that it will work even if the scheduling
            // is completely and thoroughly broken and both closures are executed "simultaneously"
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();
            OrleansTaskScheduler orleansTaskScheduler = TestHelper.InitializeSchedulerForTesting(context);
            ActivationTaskScheduler scheduler = orleansTaskScheduler.GetWorkItemGroup(context).TaskRunner;

            int n = 0;

            // ReSharper disable AccessToModifiedClosure
            Task task1 = new Task(() => { Thread.Sleep(1000); n = n + 5; });
            Task task2 = new Task(() => { n = n * 3; });
            // ReSharper restore AccessToModifiedClosure

            task1.Start(scheduler);
            task2.Start(scheduler);

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

            // N should be 15, because the two tasks should execute in order
            Assert.IsTrue(n != 0, "Work items did not get executed");
            Assert.AreEqual(15, n, "Work items executed out of order");
            Console.WriteLine("Test executed OK.");
            orleansTaskScheduler.Stop();
        }
        public void Sched_Task_TplFifoTest_TaskScheduler()
        {
            UnitTestSchedulingContext cntx = new UnitTestSchedulingContext();
            OrleansTaskScheduler scheduler = TestInternalHelper.InitializeSchedulerForTesting(cntx);
            ActivationTaskScheduler activationScheduler = scheduler.GetWorkItemGroup(cntx).TaskRunner;

            int n = 0;

            // ReSharper disable AccessToModifiedClosure
            Task task1 = new Task(() => { Thread.Sleep(1000); n = n + 5; });
            Task task2 = new Task(() => { n = n * 3; });
            // ReSharper restore AccessToModifiedClosure

            // By queuuing to ActivationTaskScheduler we guarantee single threaded ordered execution.
            // If we queued to OrleansTaskScheduler we would not guarantee that.
            task1.Start(activationScheduler);
            task2.Start(activationScheduler);

            // Pause to let things run
            Thread.Sleep(TimeSpan.FromSeconds(2));

            // N should be 15, because the two tasks should execute in order
            Assert.True(n != 0, "Work items did not get executed");
            Assert.Equal(15, n);
        }
        public void Sched_AC_RequestContext_StartNew_ContinueWith()
        {
            UnitTestSchedulingContext rootContext = new UnitTestSchedulingContext();
            OrleansTaskScheduler scheduler = TestInternalHelper.InitializeSchedulerForTesting(rootContext);

            const string key = "A";
            int val = TestConstants.random.Next();
            RequestContext.Set(key, val);

            output.WriteLine("Initial - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                SynchronizationContext.Current, TaskScheduler.Current);

            Assert.Equal(val, RequestContext.Get(key));  // "RequestContext.Get Initial"

            Task t0 = Task.Factory.StartNew(() =>
            {
                output.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                    SynchronizationContext.Current, TaskScheduler.Current);

                Assert.Equal(val, RequestContext.Get(key));  // "RequestContext.Get #0"

                Task t1 = Task.Factory.StartNew(() =>
                {
                    output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                        SynchronizationContext.Current, TaskScheduler.Current);
                    Assert.Equal(val, RequestContext.Get(key));  // "RequestContext.Get #1"
                });
                Task t2 = t1.ContinueWith((_) =>
                {
                    output.WriteLine("#2 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                        SynchronizationContext.Current, TaskScheduler.Current);
                    Assert.Equal(val, RequestContext.Get(key));  // "RequestContext.Get #2"
                });
                t2.Wait(TimeSpan.FromSeconds(5));
            });
            t0.Wait(TimeSpan.FromSeconds(10));
            Assert.True(t0.IsCompleted, "Task #0 FAULTED=" + t0.Exception);
        }
        public void Sched_Task_Turn_Execution_Order()
        {
            // A unit test that 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 masterScheduler = orleansTaskScheduler = TestHelper.InitializeSchedulerForTesting(context);
            WorkItemGroup workItemGroup = orleansTaskScheduler.GetWorkItemGroup(context);
            ActivationTaskScheduler activationScheduler = workItemGroup.TaskRunner;

            mainDone = false;
            stageNum1 = stageNum2 = 0;

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

            Task wrapper = null;
            Task finalTask1 = null;
            Task finalPromise2 = null;
            masterScheduler.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");

                    // Execution chain #1
                    Log(4, "Wrapper Task Id=" + Task.CurrentId + " creating Task chain");
                    Task task1 = Task.Factory.StartNew(() =>
                    {
                        Log(5, "#11 Inside sub-Task Id=" + Task.CurrentId);
                        Assert.AreEqual(activationScheduler, TaskScheduler.Current, "TaskScheduler.Current #11");
                        SubProcess1(11);
                    });
                    Task task2 = task1.ContinueWith((Task task) =>
                    {
                        Log(6, "#12 Inside continuation Task Id=" + Task.CurrentId);
                        Assert.AreEqual(activationScheduler, TaskScheduler.Current, "TaskScheduler.Current #12");
                        if (task.IsFaulted) throw task.Exception.Flatten();
                        SubProcess1(12);
                    });
                    Task task3 = task2.ContinueWith(task =>
                    {
                        Log(7, "#13 Inside continuation Task Id=" + Task.CurrentId);
                        Assert.AreEqual(activationScheduler, TaskScheduler.Current, "TaskScheduler.Current #13");
                        if (task.IsFaulted) throw task.Exception.Flatten();
                        SubProcess1(13);
                    });
                    finalTask1 = task3.ContinueWith(task =>
                    {
                        Log(8, "#14 Inside final continuation Task Id=" + Task.CurrentId);
                        Assert.AreEqual(activationScheduler, TaskScheduler.Current, "TaskScheduler.Current #14");
                        if (task.IsFaulted) throw task.Exception.Flatten();
                        SubProcess1(14);
                        result1.SetResult(true);
                    });

                    // Execution chain #2
                    Log(9, "Wrapper Task " + Task.CurrentId + " creating AC chain");
                    Task promise2 = Task.Factory.StartNew(() =>
                    {
                        Log(10, "#21 Inside sub-Task Id=" + Task.CurrentId);
                        Assert.AreEqual(activationScheduler, TaskScheduler.Current, "TaskScheduler.Current #21");
                        SubProcess2(21);
                    });
                    finalPromise2 = promise2.ContinueWith((_) =>
                    {
                        Log(11, "#22 Inside final continuation Task Id=" + Task.CurrentId);
                        Assert.AreEqual(activationScheduler, TaskScheduler.Current, "TaskScheduler.Current #22");
                        SubProcess2(22);
                        result2.SetResult(true);
                    });
                    finalPromise2.Ignore();

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

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

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

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

            Log(17, "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(18, "Waiting for wrapper Task Id=" + wrapper.Id + " to complete");
            bool finished = wrapper.Wait(TimeSpan.FromSeconds(2 * waitFactor));
            Log(19, "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(20, "Waiting for TaskWorkItem to complete");
            for (int i = 0; i < 15 * waitFactor; i++)
            {
                if (mainDone) break;
                Thread.Sleep(1000 * waitFactor);
            }
            Log(21, "Done waiting for TaskWorkItem to complete MainDone=" + mainDone);
            Assert.IsTrue(mainDone, "Main Task should be completed");
            Assert.IsNotNull(finalTask1, "Task chain #1 not created");
            Assert.IsNotNull(finalPromise2, "Task chain #2 not created");

            Log(22, "Waiting for final task #1 to complete");
            bool ok = finalTask1.Wait(TimeSpan.FromSeconds(4 * waitFactor));
            Log(23, "Done waiting for final task #1 complete Ok=" + ok);
            if (!ok) throw new TimeoutException();
            Assert.IsFalse(finalTask1.IsFaulted, "Final Task faulted: " + finalTask1.Exception);
            Assert.IsTrue(finalTask1.IsCompleted, "Final Task completed");
            Assert.IsTrue(result1.Task.Result, "Timeout-1");

            Log(24, "Waiting for final promise #2 to complete");
            finalPromise2.Wait(TimeSpan.FromSeconds(4 * waitFactor));
            Log(25, "Done waiting for final promise #2");
            Assert.IsFalse(finalPromise2.IsFaulted, "Final Task faulted: " + finalPromise2.Exception);
            Assert.IsTrue(finalPromise2.IsCompleted, "Final Task completed");
            Assert.IsTrue(result2.Task.Result, "Timeout-2");

            Assert.AreNotEqual(0, stageNum1, "Work items did not get executed-1");
            Assert.AreEqual(14, stageNum1, "Work items executed out of order-1");
            Assert.AreNotEqual(0, stageNum2, "Work items did not get executed-2");
            Assert.AreEqual(22, stageNum2, "Work items executed out of order-2");
        }
        public void Task_OrleansTaskScheduler()
        {
            string testName = "Task_OrleansTaskScheduler";

            var baseline = DoBaseTestRun(testName + "-Baseline", numTasks);

            var tasks = new List<Task>(numTasks);

            UnitTestSchedulingContext rootContext = new UnitTestSchedulingContext();

            TaskScheduler taskScheduler = TestInternalHelper.InitializeSchedulerForTesting(rootContext);

            QueuedTaskSchedulerTests_Set1.TimeRun(1, baseline, testName, output, () =>
            {
                for (int i = 0; i < numTasks; i++)
                {
                    string context = i.ToString();
                    Task t = CreateTask(i, context);
                    t.Start(taskScheduler);
                    tasks.Add(t);
                }

                Task.WaitAll(tasks.ToArray());
            });

            foreach (Task t in tasks)
            {
                Assert.IsTrue(t.IsCompleted, "Task is completed");
                Assert.IsFalse(t.IsFaulted, "Task did not fault");
                Assert.IsNull(t.Exception, "Task did not return an Exception");
            }
        }
        public void Sched_Task_SchedulingContext()
        {
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();
            orleansTaskScheduler = TestHelper.InitializeSchedulerForTesting(context);
            ActivationTaskScheduler scheduler = orleansTaskScheduler.GetWorkItemGroup(context).TaskRunner;

            var result = new TaskCompletionSource<bool>();
            Task endOfChain = null;
            int n = 0;

            Task wrapper = new Task(() =>
            {
                CheckRuntimeContext(context);

                // ReSharper disable AccessToModifiedClosure
                Task task1 = Task.Factory.StartNew(() =>
                {
                    Console.WriteLine("===> 1a ");
                    CheckRuntimeContext(context);
                    Thread.Sleep(1000); 
                    n = n + 3; 
                    Console.WriteLine("===> 1b");
                    CheckRuntimeContext(context);
                });
                Task task2 = task1.ContinueWith(task =>
                {
                    Console.WriteLine("===> 2");
                    CheckRuntimeContext(context);
                    n = n * 5; 
                });
                Task task3 = task2.ContinueWith(task => 
                {
                    Console.WriteLine("===> 3");
                    n = n / 5;
                    CheckRuntimeContext(context);
                });
                Task task4 = task3.ContinueWith(task => 
                {
                    Console.WriteLine("===> 4"); 
                    n = n - 2;
                    result.SetResult(true);
                    CheckRuntimeContext(context);
                });
                // ReSharper restore AccessToModifiedClosure
                endOfChain = task4.ContinueWith(task =>
                {
                    Console.WriteLine("Done Faulted={0}", task.IsFaulted);
                    CheckRuntimeContext(context);
                    Assert.IsFalse(task.IsFaulted, "Faulted with Exception=" + task.Exception);
                });
            });
            wrapper.Start(scheduler);
            bool ok = wrapper.Wait(TimeSpan.FromSeconds(1));
            if (!ok) throw new TimeoutException();

            Assert.IsFalse(wrapper.IsFaulted, "Wrapper Task Faulted with Exception=" + wrapper.Exception);
            Assert.IsTrue(wrapper.IsCompleted, "Wrapper Task completed");
            bool finished = result.Task.Wait(TimeSpan.FromSeconds(2));
            Assert.IsNotNull(endOfChain, "End of chain Task created successfully");
            Assert.IsFalse(endOfChain.IsFaulted, "Task chain Faulted with Exception=" + endOfChain.Exception);
            Assert.IsTrue(finished, "Wrapper Task completed ok");
            Assert.IsTrue(n != 0, "Work items did not get executed");
            Assert.AreEqual(1, 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_Task_SubTaskExecutionSequencing()
        {
            UnitTestSchedulingContext rootContext = new UnitTestSchedulingContext();
            OrleansTaskScheduler scheduler = TestInternalHelper.InitializeSchedulerForTesting(rootContext);

            UnitTestSchedulingContext context = new UnitTestSchedulingContext();
            scheduler.RegisterWorkContext(context);

            LogContext("Main-task " + Task.CurrentId);

            int n = 0;

            Action closure = () =>
            {
                LogContext("ClosureWorkItem-task " + Task.CurrentId);

                for (int i = 0; i < 10; i++)
                {
                    int id = -1;
                    Action action = () =>
                    {
                        id = Task.CurrentId.HasValue ? (int)Task.CurrentId : -1;

                        // ReSharper disable AccessToModifiedClosure
                        LogContext("Sub-task " + id + " n=" + n);

                        int k = n;
                        output.WriteLine("Sub-task " + id + " sleeping");
                        Thread.Sleep(100);
                        output.WriteLine("Sub-task " + id + " awake");
                        n = k + 1;
                        // ReSharper restore AccessToModifiedClosure
                    };
                    Task.Factory.StartNew(action).ContinueWith(tsk =>
                    {
                        LogContext("Sub-task " + id + "-ContinueWith");

                        output.WriteLine("Sub-task " + id + " Done");
                    });
                }
            };

            IWorkItem workItem = new ClosureWorkItem(closure);

            scheduler.QueueWorkItem(workItem, context);

            // Pause to let things run
            output.WriteLine("Main-task sleeping");
            Thread.Sleep(TimeSpan.FromSeconds(2));
            output.WriteLine("Main-task awake");

            // N should be 10, because all tasks should execute serially
            Assert.True(n != 0, "Work items did not get executed");
            Assert.Equal(10, n);  // "Work items executed concurrently"
            scheduler.Stop();
        }
        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");
        }
        public void Sched_Task_RequestContext_NewTask_ContinueWith()
        {
            UnitTestSchedulingContext rootContext = new UnitTestSchedulingContext();
            OrleansTaskScheduler scheduler = TestInternalHelper.InitializeSchedulerForTesting(rootContext);

            const string key = "K";
            int val = TestConstants.random.Next();
            RequestContext.Set(key, val);

            output.WriteLine("Initial - SynchronizationContext.Current={0} TaskScheduler.Current={1} Thread={2}",
                SynchronizationContext.Current, TaskScheduler.Current, Thread.CurrentThread.ManagedThreadId);

            Assert.Equal(val, RequestContext.Get(key));  // "RequestContext.Get Initial"

            Task t0 = new Task(() =>
            {
                output.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1} Thread={2}",
                    SynchronizationContext.Current, TaskScheduler.Current, Thread.CurrentThread.ManagedThreadId);

                Assert.Equal(val, RequestContext.Get(key));  // "RequestContext.Get #0"

                Task t1 = new Task(() =>
                {
                    output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1} Thread={2}",
                        SynchronizationContext.Current, TaskScheduler.Current, Thread.CurrentThread.ManagedThreadId);
                    Assert.Equal(val, RequestContext.Get(key));  // "RequestContext.Get #1"
                });
                Task t2 = t1.ContinueWith(task =>
                {
                    Assert.False(task.IsFaulted, "Task #1 FAULTED=" + task.Exception);

                    output.WriteLine("#2 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1} Thread={2}",
                        SynchronizationContext.Current, TaskScheduler.Current, Thread.CurrentThread.ManagedThreadId);
                    Assert.Equal(val, RequestContext.Get(key));  // "RequestContext.Get #2"
                });
                t1.Start(scheduler);
                bool ok = t2.Wait(TimeSpan.FromSeconds(5));
                if (!ok) throw new TimeoutException();
            });
            t0.Start(scheduler);
            bool finished = t0.Wait(TimeSpan.FromSeconds(10));
            if (!finished) throw new TimeoutException();
            Assert.False(t0.IsFaulted, "Task #0 FAULTED=" + t0.Exception);
        }
        public async Task OrleansSched_Test1_Bounce()
        {
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();
            OrleansTaskScheduler orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context);
            ActivationTaskScheduler scheduler = orleansTaskScheduler.GetWorkItemGroup(context).TaskRunner;

            await Run_ActivationSched_Test1(scheduler, true);
        }
        public void Sched_SimpleFifoTest()
        {
            // This is not a great test because there's a 50/50 shot that it will work even if the scheduling
            // is completely and thoroughly broken and both closures are executed "simultaneously"
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();
            OrleansTaskScheduler orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context);
            ActivationTaskScheduler scheduler = orleansTaskScheduler.GetWorkItemGroup(context).TaskRunner;

            int n = 0;
            // ReSharper disable AccessToModifiedClosure
            IWorkItem item1 = new ClosureWorkItem(() => { n = n + 5; });
            IWorkItem item2 = new ClosureWorkItem(() => { n = n * 3; });
            // ReSharper restore AccessToModifiedClosure
            orleansTaskScheduler.QueueWorkItem(item1, context);
            orleansTaskScheduler.QueueWorkItem(item2, context);

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

            // N should be 15, because the two tasks should execute in order
            Assert.True(n != 0, "Work items did not get executed");
            Assert.Equal(15, n);
            output.WriteLine("Test executed OK.");
            orleansTaskScheduler.Stop();
        }
        public void Sched_Task_ClosureWorkItem_Wait()
        {
            UnitTestSchedulingContext cntx = new UnitTestSchedulingContext();
            OrleansTaskScheduler scheduler = TestInternalHelper.InitializeSchedulerForTesting(cntx);

            const int NumTasks = 10;

            ManualResetEvent[] flags = new ManualResetEvent[NumTasks];
            for (int i = 0; i < NumTasks; i++)
            {
                flags[i] = new ManualResetEvent(false);
            }

            Task[] tasks = new Task[NumTasks];
            for (int i = 0; i < NumTasks; i++)
            {
                int taskNum = i; // Capture
                tasks[i] = new Task(() => { output.WriteLine("Inside Task-" + taskNum); flags[taskNum].WaitOne(); });
            }

            ClosureWorkItem[] workItems = new ClosureWorkItem[NumTasks];
            for (int i = 0; i < NumTasks; i++)
            {
                int taskNum = i; // Capture
                workItems[i] = new ClosureWorkItem(() =>
                {
                    output.WriteLine("Inside ClosureWorkItem-" + taskNum);
                    tasks[taskNum].Start(scheduler);
                    bool ok = tasks[taskNum].Wait(TimeSpan.FromMilliseconds(NumTasks * 100));
                    Assert.True(ok, "Wait completed successfully inside ClosureWorkItem-" + taskNum);
                });
            }

            foreach (var workItem in workItems) scheduler.QueueWorkItem(workItem, cntx);
            foreach (var flag in flags) flag.Set();
            for (int i = 0; i < tasks.Length; i++)
            {
                bool ok = tasks[i].Wait(TimeSpan.FromMilliseconds(NumTasks * 150));
                Assert.True(ok, "Wait completed successfully for Task-" + i);
            }


            for (int i = 0; i < tasks.Length; i++)
            {
                Assert.False(tasks[i].IsFaulted, "Task.IsFaulted-" + i + " Exception=" + tasks[i].Exception);
                Assert.True(tasks[i].IsCompleted, "Task.IsCompleted-" + i);
            }
        }
        public void Sched_Task_NewTask_ContinueWith_Wrapped_OrleansTaskScheduler()
        {
            UnitTestSchedulingContext rootContext = new UnitTestSchedulingContext();
            OrleansTaskScheduler scheduler = TestHelper.InitializeSchedulerForTesting(rootContext);

            Task wrapped = new Task(() =>
            {
                Console.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                    SynchronizationContext.Current, TaskScheduler.Current);

                Task t0 = new Task(() =>
                {
                    Console.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                        SynchronizationContext.Current, TaskScheduler.Current);
                    Assert.AreEqual(scheduler, TaskScheduler.Current, "TaskScheduler.Current #1");
                });
                Task t1 = t0.ContinueWith(task =>
                {
                    Assert.IsFalse(task.IsFaulted, "Task #1 Faulted=" + task.Exception);

                    Console.WriteLine("#2 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                        SynchronizationContext.Current, TaskScheduler.Current);
                    Assert.AreEqual(scheduler, TaskScheduler.Current, "TaskScheduler.Current #2");
                });
                t0.Start(scheduler);
                bool ok = t1.Wait(TimeSpan.FromSeconds(15));
                if (!ok) throw new TimeoutException();
            });
            wrapped.Start(scheduler);
            bool finished = wrapped.Wait(TimeSpan.FromSeconds(30));
            if (!finished) throw new TimeoutException();
        }
        public void Sched_Task_ClosureWorkItem_SpecificScheduler()
        {
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();
            OrleansTaskScheduler scheduler = TestInternalHelper.InitializeSchedulerForTesting(context);
            ActivationTaskScheduler activationScheduler = scheduler.GetWorkItemGroup(context).TaskRunner;

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

            Task t1 = null;
            scheduler.QueueWorkItem(new ClosureWorkItem(() =>
            {
                try
                {
                    output.WriteLine("#0 - TaskWorkItem - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                        SynchronizationContext.Current, TaskScheduler.Current);
                    Assert.Equal(activationScheduler, TaskScheduler.Current);  // "TaskScheduler.Current #0"

                    t1 = new Task(() =>
                    {
                        output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}",
                            SynchronizationContext.Current, TaskScheduler.Current);
                        Assert.Equal(scheduler, TaskScheduler.Current);  // "TaskScheduler.Current #1"
                        result1.SetResult(true);
                    });
                    t1.Start(scheduler);

                    result0.SetResult(true);
                }
                catch (Exception exc)
                {
                    result0.SetException(exc);
                }
            }), context);

            result0.Task.Wait(TimeSpan.FromSeconds(1));
            Assert.True(result0.Task.Exception == null, "Task-0 should not throw exception: " + result0.Task.Exception);
            Assert.True(result0.Task.Result, "Task-0 completed");

            Assert.NotNull(t1); // Task-1 started
            result1.Task.Wait(TimeSpan.FromSeconds(1));
            Assert.True(t1.IsCompleted, "Task-1 completed");
            Assert.False(t1.IsFaulted, "Task-1 faulted: " + t1.Exception);
            Assert.True(result1.Task.Result, "Task-1 completed");
        }
        public void Sched_Task_StartTask_Wrapped()
        {
            UnitTestSchedulingContext cntx = new UnitTestSchedulingContext();
            OrleansTaskScheduler scheduler = TestInternalHelper.InitializeSchedulerForTesting(cntx);

            ManualResetEvent pause1 = new ManualResetEvent(false);
            ManualResetEvent pause2 = new ManualResetEvent(false);
            Task task1 = new Task(() => { pause1.WaitOne(); output.WriteLine("Task-1"); });
            Task task2 = new Task(() => { pause2.WaitOne(); output.WriteLine("Task-2"); });

            Task wrapper1 = new Task(() =>
            {
                task1.Start(scheduler);
                bool ok = task1.Wait(TimeSpan.FromMilliseconds(100));
                if (!ok) throw new TimeoutException();
            });
            Task wrapper2 = new Task(() =>
            {
                task2.Start(scheduler);
                bool ok = task2.Wait(TimeSpan.FromMilliseconds(100));
                if (!ok) throw new TimeoutException();
            });

            pause1.Set();
            wrapper1.Start(scheduler);
            bool ok1 = wrapper1.Wait(TimeSpan.FromMilliseconds(1000));
            if (!ok1) throw new TimeoutException();

            Assert.True(task1.IsCompleted, "Task.IsCompleted-1");
            Assert.False(task1.IsFaulted, "Task.IsFaulted-1");

            wrapper2.Start(scheduler);
            pause2.Set();
            bool finished = wrapper2.Wait(TimeSpan.FromMilliseconds(100));
            if (!finished) throw new TimeoutException();

            Assert.True(task2.IsCompleted, "Task.IsCompleted-2");
            Assert.False(task2.IsFaulted, "Task.IsFaulted-2");
        }
        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 void Sched_Task_StartTask_Wait_Wrapped()
        {
            UnitTestSchedulingContext cntx = new UnitTestSchedulingContext();
            OrleansTaskScheduler scheduler = TestInternalHelper.InitializeSchedulerForTesting(cntx);

            const int NumTasks = 100;

            ManualResetEvent[] flags = new ManualResetEvent[NumTasks];
            for (int i = 0; i < NumTasks; i++)
            {
                flags[i] = new ManualResetEvent(false);
            }

            Task[] tasks = new Task[NumTasks];
            for (int i = 0; i < NumTasks; i++)
            {
                int taskNum = i; // Capture
                tasks[i] = new Task(() => { output.WriteLine("Inside Task-" + taskNum); flags[taskNum].WaitOne(); });
                output.WriteLine("Created Task-" + taskNum + " Id=" + tasks[taskNum].Id);
            }

            Task[] wrappers = new Task[NumTasks];
            for (int i = 0; i < NumTasks; i++)
            {
                int taskNum = i; // Capture
                wrappers[i] = new Task(() =>
                {
                    output.WriteLine("Inside Wrapper-" + taskNum); 
                    tasks[taskNum].Start(scheduler);
                });
                wrappers[i].ContinueWith(t =>
                {
                    Assert.False(t.IsFaulted, "Warpper.IsFaulted-" + taskNum + " " + t.Exception);
                    Assert.True(t.IsCompleted, "Wrapper.IsCompleted-" + taskNum);
                });
                output.WriteLine("Created Wrapper-" + taskNum + " Task.Id=" + wrappers[taskNum].Id);
            }

            foreach (var wrapper in wrappers) wrapper.Start(scheduler);
            foreach (var flag in flags) flag.Set();
            for (int i = 0; i < wrappers.Length; i++)
            {
                bool ok = wrappers[i].Wait(TimeSpan.FromMilliseconds(NumTasks * 150 * 2));
                Assert.True(ok, "Wait completed successfully for Wrapper-" + i);
            }

            for (int i = 0; i < tasks.Length; i++)
            {
                bool ok = tasks[i].Wait(TimeSpan.FromMilliseconds(NumTasks * 150 * 2));
                Assert.True(ok, "Wait completed successfully for Task-" + i);
                Assert.False(tasks[i].IsFaulted, "Task.IsFaulted-" + i + " " + tasks[i].Exception);
                Assert.True(tasks[i].IsCompleted, "Task.IsCompleted-" + i);
            }
        }
 public void TestInit()
 {
     context = new UnitTestSchedulingContext();
     masterScheduler = TestInternalHelper.InitializeSchedulerForTesting(context);
 }