diff --git a/Test/TaskHubStressTest/.nuget/NuGet.Config b/Test/TaskHubStressTest/.nuget/NuGet.Config
new file mode 100644
index 000000000..67f8ea046
--- /dev/null
+++ b/Test/TaskHubStressTest/.nuget/NuGet.Config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Test/TaskHubStressTest/.nuget/NuGet.targets b/Test/TaskHubStressTest/.nuget/NuGet.targets
new file mode 100644
index 000000000..83fe90601
--- /dev/null
+++ b/Test/TaskHubStressTest/.nuget/NuGet.targets
@@ -0,0 +1,136 @@
+
+
+
+ $(MSBuildProjectDirectory)\..\
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+ $([System.IO.Path]::Combine($(SolutionDir), ".nuget"))
+ $([System.IO.Path]::Combine($(ProjectDir), "packages.config"))
+
+
+
+
+ $(SolutionDir).nuget
+ packages.config
+
+
+
+
+ $(NuGetToolsPath)\NuGet.exe
+ @(PackageSource)
+
+ "$(NuGetExePath)"
+ mono --runtime=v4.0.30319 $(NuGetExePath)
+
+ $(TargetDir.Trim('\\'))
+
+ -RequireConsent
+ -NonInteractive
+
+ "$(SolutionDir) "
+ "$(SolutionDir)"
+
+
+ $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)
+ $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols
+
+
+
+ RestorePackages;
+ $(BuildDependsOn);
+
+
+
+
+ $(BuildDependsOn);
+ BuildPackage;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Test/TaskHubStressTest/TaskHubStressTest.sln b/Test/TaskHubStressTest/TaskHubStressTest.sln
new file mode 100644
index 000000000..8c48c00d7
--- /dev/null
+++ b/Test/TaskHubStressTest/TaskHubStressTest.sln
@@ -0,0 +1,33 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TaskHubStressTest", "TaskHubStressTest\TaskHubStressTest.csproj", "{96980359-8003-4500-B97B-949A7FE01F31}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{3EB529F2-51AE-42CE-9560-706DB5B2C178}"
+ ProjectSection(SolutionItems) = preProject
+ .nuget\NuGet.Config = .nuget\NuGet.Config
+ .nuget\NuGet.exe = .nuget\NuGet.exe
+ .nuget\NuGet.targets = .nuget\NuGet.targets
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Framework", "..\..\Framework\Framework.csproj", "{6F5D2EAD-726D-4FE5-A575-AEB96D1CCE37}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {96980359-8003-4500-B97B-949A7FE01F31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {96980359-8003-4500-B97B-949A7FE01F31}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {96980359-8003-4500-B97B-949A7FE01F31}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {96980359-8003-4500-B97B-949A7FE01F31}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6F5D2EAD-726D-4FE5-A575-AEB96D1CCE37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6F5D2EAD-726D-4FE5-A575-AEB96D1CCE37}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6F5D2EAD-726D-4FE5-A575-AEB96D1CCE37}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6F5D2EAD-726D-4FE5-A575-AEB96D1CCE37}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Test/TaskHubStressTest/TaskHubStressTest/App.config b/Test/TaskHubStressTest/TaskHubStressTest/App.config
new file mode 100644
index 000000000..9a4e3d923
--- /dev/null
+++ b/Test/TaskHubStressTest/TaskHubStressTest/App.config
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Test/TaskHubStressTest/TaskHubStressTest/DriverOrchestration.cs b/Test/TaskHubStressTest/TaskHubStressTest/DriverOrchestration.cs
new file mode 100644
index 000000000..290462516
--- /dev/null
+++ b/Test/TaskHubStressTest/TaskHubStressTest/DriverOrchestration.cs
@@ -0,0 +1,33 @@
+namespace TaskHubStressTest
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ using DurableTask;
+
+ public class DriverOrchestration : TaskOrchestration
+ {
+ public override async Task RunTask(OrchestrationContext context, DriverOrchestrationData data)
+ {
+ int result = 0;
+ List> results = new List>();
+ int i = 0;
+ for (; i < data.NumberOfParallelTasks; i++)
+ {
+ results.Add(context.CreateSubOrchestrationInstance(typeof(TestOrchestration), data.SubOrchestrationData));
+ }
+
+ int[] counters = await Task.WhenAll(results.ToArray());
+ result = counters.Max();
+
+ if (data.NumberOfIteration > 0)
+ {
+ data.NumberOfIteration--;
+ context.ContinueAsNew(data);
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/Test/TaskHubStressTest/TaskHubStressTest/DriverOrchestrationData.cs b/Test/TaskHubStressTest/TaskHubStressTest/DriverOrchestrationData.cs
new file mode 100644
index 000000000..ecf8dfc91
--- /dev/null
+++ b/Test/TaskHubStressTest/TaskHubStressTest/DriverOrchestrationData.cs
@@ -0,0 +1,9 @@
+namespace TaskHubStressTest
+{
+ public class DriverOrchestrationData
+ {
+ public int NumberOfParallelTasks { get; set; }
+ public int NumberOfIteration { get; set; }
+ public TestOrchestrationData SubOrchestrationData { get; set; }
+ }
+}
diff --git a/Test/TaskHubStressTest/TaskHubStressTest/Options.cs b/Test/TaskHubStressTest/TaskHubStressTest/Options.cs
new file mode 100644
index 000000000..c611d15d0
--- /dev/null
+++ b/Test/TaskHubStressTest/TaskHubStressTest/Options.cs
@@ -0,0 +1,40 @@
+namespace TaskHubStressTest
+{
+ using CommandLine;
+ using CommandLine.Text;
+ using System.Text;
+
+ class Options
+ {
+ [Option('c', "create-hub", DefaultValue = false,
+ HelpText = "Create Orchestration Hub.")]
+ public bool CreateHub { get; set; }
+
+ [Option('s', "start-instance", DefaultValue = null,
+ HelpText = "Start Driver Instance")]
+ public string StartInstance { get; set; }
+
+ [Option('i', "instance-id",
+ HelpText = "Instance id for new orchestration instance.")]
+ public string InstanceId { get; set; }
+
+ [HelpOption]
+ public string GetUsage()
+ {
+ // this without using CommandLine.Text
+ // or using HelpText.AutoBuild
+
+ var help = new HelpText
+ {
+ Heading = new HeadingInfo("TaskHubStressTest", "1.0"),
+ AdditionalNewLineAfterOption = true,
+ AddDashesToOption = true
+ };
+ help.AddPreOptionsLine("Usage: TaskHubStressTest.exe -c");
+ help.AddPreOptionsLine("Usage: TaskHubStressTest.exe -c -s ");
+ help.AddPreOptionsLine("Usage: TaskHubStressTest.exe -i ");
+ help.AddOptions(this);
+ return help;
+ }
+ }
+}
diff --git a/Test/TaskHubStressTest/TaskHubStressTest/OrchestrationConsoleTraceListener.cs b/Test/TaskHubStressTest/TaskHubStressTest/OrchestrationConsoleTraceListener.cs
new file mode 100644
index 000000000..60360eac5
--- /dev/null
+++ b/Test/TaskHubStressTest/TaskHubStressTest/OrchestrationConsoleTraceListener.cs
@@ -0,0 +1,38 @@
+namespace TaskHubStressTest
+{
+ using System;
+ using System.Linq;
+ using System.Diagnostics;
+
+ class OrchestrationConsoleTraceListener : ConsoleTraceListener
+ {
+ public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message)
+ {
+ try
+ {
+ var dict = message.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
+ .Select(part => part.Split('='))
+ .ToDictionary(split => split[0], split => split[1]);
+ string iid;
+ if (dict.TryGetValue("iid", out iid))
+ {
+ string toWrite = string.Format("[{0} {1}] {2}", DateTime.Now, iid, dict["msg"]);
+ Console.WriteLine(toWrite);
+ Debug.WriteLine(toWrite);
+ }
+ else
+ {
+ string toWrite = string.Format("[{0}] {1}", DateTime.Now, dict["msg"]);
+ Console.WriteLine(toWrite);
+ Debug.WriteLine(toWrite);
+ }
+ }
+ catch (Exception exception)
+ {
+ string toWrite = string.Format("Exception while parsing trace: {0}\n\t", exception.Message, exception.StackTrace);
+ Console.WriteLine(toWrite);
+ Debug.WriteLine(toWrite);
+ }
+ }
+ }
+}
diff --git a/Test/TaskHubStressTest/TaskHubStressTest/OrchestrationFileTraceListener.cs b/Test/TaskHubStressTest/TaskHubStressTest/OrchestrationFileTraceListener.cs
new file mode 100644
index 000000000..af6068a52
--- /dev/null
+++ b/Test/TaskHubStressTest/TaskHubStressTest/OrchestrationFileTraceListener.cs
@@ -0,0 +1,63 @@
+namespace TaskHubStressTest
+{
+ using System;
+ using System.Linq;
+ using System.Diagnostics;
+
+ class OrchestrationFileTraceListener : TextWriterTraceListener
+ {
+ public OrchestrationFileTraceListener(string file)
+ : base(file)
+ {
+ }
+
+ public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id)
+ {
+ base.TraceEvent(eventCache, source, eventType, id);
+ }
+
+ public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args)
+ {
+ string message = format;
+ try
+ {
+ if (args != null && args.Length > 0)
+ {
+ message = string.Format(format, args);
+ }
+ }
+ catch (Exception ex)
+ {
+ message = "msg=Cannot format message";
+ }
+
+ this.TraceEvent(eventCache, source, eventType, id, message);
+ }
+
+ public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message)
+ {
+ try
+ {
+ var dict = message.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
+ .Select(part => part.Split('='))
+ .ToDictionary(split => split[0], split => split[1]);
+ string iid;
+ if (dict.TryGetValue("iid", out iid))
+ {
+ string toWrite = string.Format("[{0} {1}] {2}", DateTime.Now, iid, dict["msg"]);
+ base.WriteLine(toWrite);
+ }
+ else
+ {
+ string toWrite = string.Format("[{0}] {1}", DateTime.Now, dict["msg"]);
+ base.WriteLine(toWrite);
+ }
+ }
+ catch (Exception exception)
+ {
+ string toWrite = string.Format("Exception while parsing trace: {0}\n\t", exception.Message, exception.StackTrace);
+ base.WriteLine(toWrite);
+ }
+ }
+ }
+}
diff --git a/Test/TaskHubStressTest/TaskHubStressTest/Program.cs b/Test/TaskHubStressTest/TaskHubStressTest/Program.cs
new file mode 100644
index 000000000..f9946d9e9
--- /dev/null
+++ b/Test/TaskHubStressTest/TaskHubStressTest/Program.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using DurableTask;
+
+namespace TaskHubStressTest
+{
+ class Program
+ {
+ static Options options = new Options();
+
+ static void Main(string[] args)
+ {
+ string tableConnectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
+ if (CommandLine.Parser.Default.ParseArgumentsStrict(args, options))
+ {
+ string connectionString = ConfigurationManager.ConnectionStrings["Microsoft.ServiceBus.ConnectionString"].ConnectionString;
+ string taskHubName = ConfigurationManager.AppSettings["TaskHubName"];
+
+ TaskHubClient taskHubClient = new TaskHubClient(taskHubName, connectionString, tableConnectionString);
+ TaskHubWorkerSettings settings = new TaskHubWorkerSettings();
+ settings.TaskOrchestrationDispatcherSettings.CompressOrchestrationState = bool.Parse(ConfigurationManager.AppSettings["CompressOrchestrationState"]);
+ settings.TaskActivityDispatcherSettings.MaxConcurrentActivities = int.Parse(ConfigurationManager.AppSettings["MaxConcurrentActivities"]);
+ settings.TaskOrchestrationDispatcherSettings.MaxConcurrentOrchestrations = int.Parse(ConfigurationManager.AppSettings["MaxConcurrentOrchestrations"]);
+ TaskHubWorker taskHub = new TaskHubWorker(taskHubName, connectionString, tableConnectionString, settings);
+
+ if (options.CreateHub)
+ {
+ taskHub.CreateHub();
+ }
+
+ OrchestrationInstance instance = null;
+ string instanceId = options.StartInstance;
+
+ if (!string.IsNullOrWhiteSpace(instanceId))
+ {
+ instance = taskHubClient.CreateOrchestrationInstance(typeof(DriverOrchestration), instanceId, new DriverOrchestrationData
+ {
+ NumberOfIteration = int.Parse(ConfigurationManager.AppSettings["DriverOrchestrationIterations"]),
+ NumberOfParallelTasks = int.Parse(ConfigurationManager.AppSettings["DriverOrchestrationParallelTasks"]),
+ SubOrchestrationData = new TestOrchestrationData
+ {
+ NumberOfParallelTasks = int.Parse(ConfigurationManager.AppSettings["ChildOrchestrationParallelTasks"]),
+ NumberOfSerialTasks = int.Parse(ConfigurationManager.AppSettings["ChildOrchestrationSerialTasks"]),
+ MaxDelayInSeconds = int.Parse(ConfigurationManager.AppSettings["TestTaskMaxDelayInMinutes"]),
+ },
+ });
+ }
+ else
+ {
+ instance = new OrchestrationInstance { InstanceId = options.InstanceId };
+ }
+
+ Stopwatch stopWatch = new Stopwatch();
+ stopWatch.Start();
+
+ TestTask testTask = new TestTask();
+ taskHub.AddTaskActivities(testTask);
+ taskHub.AddTaskOrchestrations(typeof(DriverOrchestration));
+ taskHub.AddTaskOrchestrations(typeof(TestOrchestration));
+ taskHub.Start();
+
+ int testTimeoutInSeconds = int.Parse(ConfigurationManager.AppSettings["TestTimeoutInSeconds"]);
+ OrchestrationState state = WaitForInstance(taskHubClient, instance, testTimeoutInSeconds);
+ stopWatch.Stop();
+ Console.WriteLine("Orchestration Status: " + state.OrchestrationStatus.ToString());
+ Console.WriteLine("Orchestration Result: " + state.Output);
+ Console.WriteLine("Counter: " + testTask.counter);
+
+ TimeSpan totalTime = stopWatch.Elapsed;
+ string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
+ totalTime.Hours, totalTime.Minutes, totalTime.Seconds,
+ totalTime.Milliseconds / 10);
+ Console.WriteLine("Total Time: " + elapsedTime);
+
+ taskHub.Stop();
+ }
+
+ }
+
+ public static OrchestrationState WaitForInstance(TaskHubClient taskHubClient, OrchestrationInstance instance, int timeoutSeconds)
+ {
+ OrchestrationStatus status = OrchestrationStatus.Running;
+ if (instance == null || string.IsNullOrWhiteSpace(instance.InstanceId))
+ {
+ throw new ArgumentException("instance");
+ }
+
+ int sleepForSeconds = 30;
+ while (timeoutSeconds > 0)
+ {
+ try
+ {
+ var state = taskHubClient.GetOrchestrationState(instance.InstanceId);
+ if (state != null) status = state.OrchestrationStatus;
+ if (status == OrchestrationStatus.Running)
+ {
+ System.Threading.Thread.Sleep(sleepForSeconds * 1000);
+ timeoutSeconds -= sleepForSeconds;
+ }
+ else
+ {
+ // Session state deleted after completion
+ return state;
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(string.Format("Error retrieving state for instance [instanceId: '{0}', executionId: '{1}'].", instance.InstanceId, instance.ExecutionId));
+ Console.WriteLine(ex.ToString());
+ }
+ }
+
+ throw new TimeoutException("Timeout expired: " + timeoutSeconds.ToString());
+ }
+ }
+}
diff --git a/Test/TaskHubStressTest/TaskHubStressTest/Properties/AssemblyInfo.cs b/Test/TaskHubStressTest/TaskHubStressTest/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..afe71842a
--- /dev/null
+++ b/Test/TaskHubStressTest/TaskHubStressTest/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TaskHubStressTest")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("TaskHubStressTest")]
+[assembly: AssemblyCopyright("Copyright © 2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("d66d425c-6748-467d-83d1-b44945cc38c8")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Test/TaskHubStressTest/TaskHubStressTest/TaskHubStressTest.csproj b/Test/TaskHubStressTest/TaskHubStressTest/TaskHubStressTest.csproj
new file mode 100644
index 000000000..17dbee575
--- /dev/null
+++ b/Test/TaskHubStressTest/TaskHubStressTest/TaskHubStressTest.csproj
@@ -0,0 +1,111 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {96980359-8003-4500-B97B-949A7FE01F31}
+ Exe
+ Properties
+ TaskHubStressTest
+ TaskHubStressTest
+ v4.5
+ 512
+ ..\
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll
+
+
+ ..\packages\ImpromptuInterface.6.2.2\lib\net40\ImpromptuInterface.dll
+
+
+ ..\packages\Microsoft.Data.Edm.5.2.0\lib\net40\Microsoft.Data.Edm.dll
+
+
+ ..\packages\Microsoft.Data.OData.5.2.0\lib\net40\Microsoft.Data.OData.dll
+
+
+ ..\packages\WindowsAzure.ServiceBus.2.2.4.0\lib\net40-full\Microsoft.ServiceBus.dll
+
+
+ ..\packages\Microsoft.WindowsAzure.ConfigurationManager.2.0.3\lib\net40\Microsoft.WindowsAzure.Configuration.dll
+
+
+ False
+ ..\packages\WindowsAzure.Storage.2.1.0.4\lib\net40\Microsoft.WindowsAzure.Storage.dll
+
+
+ ..\packages\Newtonsoft.Json.5.0.6\lib\net45\Newtonsoft.Json.dll
+
+
+
+
+
+
+
+
+ ..\packages\System.Spatial.5.2.0\lib\net40\System.Spatial.dll
+
+
+
+
+
+
+
+ {6f5d2ead-726d-4fe5-a575-aeb96d1cce37}
+ Microsoft.ServiceBus.DurableTask
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Designer
+
+
+ Designer
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Test/TaskHubStressTest/TaskHubStressTest/TestOrchestration.cs b/Test/TaskHubStressTest/TaskHubStressTest/TestOrchestration.cs
new file mode 100644
index 000000000..11e7cff95
--- /dev/null
+++ b/Test/TaskHubStressTest/TaskHubStressTest/TestOrchestration.cs
@@ -0,0 +1,43 @@
+
+namespace TaskHubStressTest
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ using DurableTask;
+
+ public class TestOrchestration : TaskOrchestration
+ {
+ public override async Task RunTask(OrchestrationContext context, TestOrchestrationData data)
+ {
+ int result = 0;
+ List> results = new List>();
+ int i = 0;
+ int j = 0;
+ for (; i < data.NumberOfParallelTasks; i++)
+ {
+ results.Add(context.ScheduleTask(typeof(TestTask), new TestTaskData
+ {
+ TaskId = "ParallelTask: " + i.ToString(),
+ MaxDelayInMinutes = data.MaxDelayInSeconds,
+ }));
+ }
+
+ int[] counters = await Task.WhenAll(results.ToArray());
+ result = counters.Max();
+
+ for (; j < data.NumberOfSerialTasks; j++)
+ {
+ int c = await context.ScheduleTask(typeof(TestTask), new TestTaskData
+ {
+ TaskId = "SerialTask" + (i + j).ToString(),
+ MaxDelayInMinutes = data.MaxDelayInSeconds,
+ });
+ result = Math.Max(result, c);
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/Test/TaskHubStressTest/TaskHubStressTest/TestOrchestrationData.cs b/Test/TaskHubStressTest/TaskHubStressTest/TestOrchestrationData.cs
new file mode 100644
index 000000000..98ae386ef
--- /dev/null
+++ b/Test/TaskHubStressTest/TaskHubStressTest/TestOrchestrationData.cs
@@ -0,0 +1,9 @@
+namespace TaskHubStressTest
+{
+ public class TestOrchestrationData
+ {
+ public int NumberOfParallelTasks { get; set; }
+ public int NumberOfSerialTasks { get; set; }
+ public int MaxDelayInSeconds { get; set; }
+ }
+}
diff --git a/Test/TaskHubStressTest/TaskHubStressTest/TestTask.cs b/Test/TaskHubStressTest/TaskHubStressTest/TestTask.cs
new file mode 100644
index 000000000..48997a560
--- /dev/null
+++ b/Test/TaskHubStressTest/TaskHubStressTest/TestTask.cs
@@ -0,0 +1,32 @@
+namespace TaskHubStressTest
+{
+ using System;
+ using System.Threading;
+ using System.Threading.Tasks;
+ using DurableTask;
+
+ public sealed class TestTask : AsyncTaskActivity
+ {
+ public int counter = 0;
+
+ public TestTask()
+ {
+ }
+
+ protected override async Task ExecuteAsync(TaskContext context, TestTaskData input)
+ {
+ int c = Interlocked.Increment(ref this.counter);
+ OrchestrationInstance instance = context.OrchestrationInstance;
+ Random random = new Random();
+ int minutesToSleep = random.Next(0, input.MaxDelayInMinutes);
+
+ Console.WriteLine(string.Format("[InstanceId: {0}, ExecutionId: {1}, TaskId: {2}, Counter: {3}] ---> Sleeping for '{4}'",
+ instance.InstanceId, instance.ExecutionId, input.TaskId, c, minutesToSleep));
+
+ await Task.Delay(TimeSpan.FromMinutes(minutesToSleep));
+
+ return c;
+ }
+
+ }
+}
diff --git a/Test/TaskHubStressTest/TaskHubStressTest/TestTaskData.cs b/Test/TaskHubStressTest/TaskHubStressTest/TestTaskData.cs
new file mode 100644
index 000000000..86ef6210f
--- /dev/null
+++ b/Test/TaskHubStressTest/TaskHubStressTest/TestTaskData.cs
@@ -0,0 +1,8 @@
+namespace TaskHubStressTest
+{
+ public class TestTaskData
+ {
+ public string TaskId { get; set; }
+ public int MaxDelayInMinutes { get; set; }
+ }
+}
diff --git a/Test/TaskHubStressTest/TaskHubStressTest/packages.config b/Test/TaskHubStressTest/TaskHubStressTest/packages.config
new file mode 100644
index 000000000..485fd5596
--- /dev/null
+++ b/Test/TaskHubStressTest/TaskHubStressTest/packages.config
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file