Пример #1
0
        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());
        }
Пример #2
0
        /// <summary>
        ///     Create a new orchestration of the specified name and version
        /// </summary>
        /// <param name="name">Name of the orchestration as specified by the ObjectCreator</param>
        /// <param name="version">Name of the orchestration as specified by the ObjectCreator</param>
        /// <param name="instanceId">Instance id for the orchestration to be created, must be unique across the Task Hub</param>
        /// <param name="input">Input parameter to the specified TaskOrchestration</param>
        /// <param name="tags">Dictionary of key/value tags associated with this instance</param>
        /// <returns>OrchestrationInstance that represents the orchestration that was created</returns>
        public async Task <OrchestrationInstance> CreateOrchestrationInstanceAsync(string name, string version,
                                                                                   string instanceId,
                                                                                   object input, IDictionary <string, string> tags)
        {
            if (string.IsNullOrWhiteSpace(instanceId))
            {
                instanceId = Guid.NewGuid().ToString("N");
            }

            var orchestrationInstance = new OrchestrationInstance
            {
                InstanceId  = instanceId,
                ExecutionId = Guid.NewGuid().ToString("N"),
            };

            string serializedInput = defaultConverter.Serialize(input);
            string serializedtags  = tags != null?defaultConverter.Serialize(tags) : null;

            var startedEvent = new ExecutionStartedEvent(-1, serializedInput)
            {
                Tags    = serializedtags,
                Name    = name,
                Version = version,
                OrchestrationInstance = orchestrationInstance
            };

            var taskMessage = new TaskMessage
            {
                OrchestrationInstance = orchestrationInstance,
                Event = startedEvent
            };

            BrokeredMessage brokeredMessage = Utils.GetBrokeredMessageFromObject(taskMessage,
                                                                                 settings.MessageCompressionSettings);

            brokeredMessage.SessionId = instanceId;

            MessageSender sender =
                await messagingFactory.CreateMessageSenderAsync(orchestratorEntityName).ConfigureAwait(false);

            await sender.SendAsync(brokeredMessage).ConfigureAwait(false);

            await sender.CloseAsync().ConfigureAwait(false);

            return(orchestrationInstance);
        }
Пример #3
0
        public static string GetInstanceNotCompletedMessage(TaskHubClient taskHubClient, OrchestrationInstance instance,
            int timeWaited)
        {
            if (instance == null || string.IsNullOrWhiteSpace(instance.InstanceId))
            {
                throw new ArgumentException("instance");
            }

            string history = PrintHistory(taskHubClient, instance);
            string message = string.Format("Instance '{0}' not completed within {1} seconds.\n History: {2}", instance,
                timeWaited, history);

            return message;
        }
Пример #4
0
 public static string PrintHistory(TaskHubClient taskHubClient, OrchestrationInstance instance)
 {
     return taskHubClient.GetOrchestrationHistory(instance);
 }
Пример #5
0
        static void Main(string[] args)
        {
            if (CommandLine.Parser.Default.ParseArgumentsStrict(args, options))
            {
                string servicebusConnectionString = Program.GetSetting("ServiceBusConnectionString");
                string storageConnectionString = Program.GetSetting("StorageConnectionString");
                string taskHubName = ConfigurationManager.AppSettings["taskHubName"];

                TaskHubClient taskHubClient = new TaskHubClient(taskHubName, servicebusConnectionString, storageConnectionString);
                TaskHubWorker taskHub = new TaskHubWorker(taskHubName, servicebusConnectionString, storageConnectionString);

                if (options.CreateHub)
                {
                    taskHub.CreateHub();
                }

                if (!string.IsNullOrWhiteSpace(options.StartInstance))
                {
                    string instanceId = options.InstanceId;
                    OrchestrationInstance instance = null;
                    switch (options.StartInstance)
                    {
                        case "Greetings":
                            instance = taskHubClient.CreateOrchestrationInstance(typeof(GreetingsOrchestration), instanceId, null);
                            break;
                        case "Greetings2":
                            if (options.Parameters == null || options.Parameters.Length != 1)
                            {
                                throw new ArgumentException("parameters");
                            }
                            instance = taskHubClient.CreateOrchestrationInstance(typeof(GreetingsOrchestration2), instanceId, 
                                int.Parse(options.Parameters[0]));
                            break;
                        case "Cron":
                            // Sample Input: "0 12 * */2 Mon"
                            instance = taskHubClient.CreateOrchestrationInstance(typeof(CronOrchestration), instanceId, 
                                (options.Parameters != null && options.Parameters.Length > 0) ? options.Parameters[0] : null);
                            break;
                        case "Average":
                            // Sample Input: "1 50 10"
                            if (options.Parameters == null || options.Parameters.Length != 3)
                            {
                                throw new ArgumentException("parameters");
                            }
                            int[] input = options.Parameters.Select(p => int.Parse(p)).ToArray();
                            instance = taskHubClient.CreateOrchestrationInstance(typeof(AverageCalculatorOrchestration), instanceId, input);
                            break;
                        case "ErrorHandling":
                            instance = taskHubClient.CreateOrchestrationInstance(typeof(ErrorHandlingOrchestration), instanceId, null);
                            break;
                        case "Signal":
                            instance = taskHubClient.CreateOrchestrationInstance(typeof(SignalOrchestration), instanceId, null);
                            break;
                        case "Replat":
                            instance = taskHubClient.CreateOrchestrationInstance(typeof(MigrateOrchestration), instanceId,
                                new MigrateOrchestrationData() { SubscriptionId = "03a1cd39-47ac-4a57-9ff5-a2c2a2a76088", IsDisabled = false });
                            break;
                        default:
                            throw new Exception("Unsupported Orchestration Name: " + options.StartInstance);
                    }

                    Console.WriteLine("Workflow Instance Started: " + instance);
                }
                else if (!string.IsNullOrWhiteSpace(options.Signal))
                {
                    if (string.IsNullOrWhiteSpace(options.InstanceId)) 
                    {
                        throw new ArgumentException("instantceId");
                    }
                    if (options.Parameters == null || options.Parameters.Length != 1)
                    {
                        throw new ArgumentException("parameters");

                    }
                    string instanceId = options.InstanceId;
                    OrchestrationInstance instance = new OrchestrationInstance { InstanceId = instanceId };
                    taskHubClient.RaiseEvent(instance, options.Signal, options.Parameters[0]);
                }

                if (!options.SkipWorker)
                {
                    try
                    {
                        taskHub.AddTaskOrchestrations(typeof(GreetingsOrchestration), typeof(GreetingsOrchestration2), typeof(CronOrchestration),
                                                            typeof (AverageCalculatorOrchestration), typeof (ErrorHandlingOrchestration), typeof (SignalOrchestration));
                        taskHub.AddTaskOrchestrations(typeof(MigrateOrchestration));

                        taskHub.AddTaskActivities(new GetUserTask(), new SendGreetingTask(), new CronTask(), new ComputeSumTask(), new GoodTask(), new BadTask(), new CleanupTask(),
                                                             new EmailTask());
                        taskHub.AddTaskActivitiesFromInterface<IManagementSqlOrchestrationTasks>(new ManagementSqlOrchestrationTasks());
                        taskHub.AddTaskActivitiesFromInterface<IMigrationTasks>(new MigrationTasks());

                        taskHub.Start();

                        Console.WriteLine("Press any key to quit.");
                        Console.ReadLine();

                        taskHub.Stop(true);
                    }
                    catch (Exception)
                    {
                        // silently eat any unhadled exceptions.
                    }
                }
            }
        }
Пример #6
0
        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();
            }

        }
Пример #7
0
 /// <summary>
 ///     Get a list of orchestration states from the instance storage table for the
 ///     most current execution (generation) of the specified instance.
 ///     Throws if an Azure Storage account was not specified in the constructor.
 /// </summary>
 /// <param name="instance">Instance</param>
 /// <returns>The OrchestrationState of the specified instanceId or null if not found</returns>
 public Task <OrchestrationState> GetOrchestrationStateAsync(OrchestrationInstance instance)
 {
     return(GetOrchestrationStateAsync(instance.InstanceId, instance.ExecutionId));
 }
Пример #8
0
 /// <summary>
 ///     Forcefully terminate the specified orchestration instance with a reason
 /// </summary>
 /// <param name="orchestrationInstance">Instance to terminate</param>
 /// <param name="reason">Reason for terminating the instance</param>
 public void TerminateInstance(OrchestrationInstance orchestrationInstance, string reason)
 {
     Utils.AsyncExceptionWrapper(() => TerminateInstanceAsync(orchestrationInstance, reason).Wait());
 }
Пример #9
0
 /// <summary>
 ///     Forcefully terminate the specified orchestration instance
 /// </summary>
 /// <param name="orchestrationInstance">Instance to terminate</param>
 public void TerminateInstance(OrchestrationInstance orchestrationInstance)
 {
     TerminateInstance(orchestrationInstance, string.Empty);
 }
Пример #10
0
        /// <summary>
        ///     Forcefully terminate the specified orchestration instance with a reason
        /// </summary>
        /// <param name="orchestrationInstance">Instance to terminate</param>
        /// <param name="reason">Reason for terminating the instance</param>
        public async Task TerminateInstanceAsync(OrchestrationInstance orchestrationInstance, string reason)
        {
            if (orchestrationInstance == null || string.IsNullOrWhiteSpace(orchestrationInstance.InstanceId))
            {
                throw new ArgumentException("orchestrationInstance");
            }

            string instanceId = orchestrationInstance.InstanceId;

            var taskMessage = new TaskMessage
            {
                OrchestrationInstance = orchestrationInstance,
                Event = new ExecutionTerminatedEvent(-1, reason)
            };

            BrokeredMessage brokeredMessage = Utils.GetBrokeredMessageFromObject(taskMessage,
                settings.MessageCompressionSettings);
            brokeredMessage.SessionId = instanceId;

            MessageSender sender =
                await messagingFactory.CreateMessageSenderAsync(orchestratorEntityName).ConfigureAwait(false);
            await sender.SendAsync(brokeredMessage).ConfigureAwait(false);
            await sender.CloseAsync().ConfigureAwait(false);
        }
Пример #11
0
 /// <summary>
 ///     Forcefully terminate the specified orchestration instance with a reason
 /// </summary>
 /// <param name="orchestrationInstance">Instance to terminate</param>
 /// <param name="reason">Reason for terminating the instance</param>
 public void TerminateInstance(OrchestrationInstance orchestrationInstance, string reason)
 {
     Utils.AsyncExceptionWrapper(() => TerminateInstanceAsync(orchestrationInstance, reason).Wait());
 }
Пример #12
0
 /// <summary>
 ///     Forcefully terminate the specified orchestration instance
 /// </summary>
 /// <param name="orchestrationInstance">Instance to terminate</param>
 public Task TerminateInstanceAsync(OrchestrationInstance orchestrationInstance)
 {
     return TerminateInstanceAsync(orchestrationInstance, string.Empty);
 }
Пример #13
0
 /// <summary>
 ///     Forcefully terminate the specified orchestration instance
 /// </summary>
 /// <param name="orchestrationInstance">Instance to terminate</param>
 public void TerminateInstance(OrchestrationInstance orchestrationInstance)
 {
     TerminateInstance(orchestrationInstance, string.Empty);
 }
Пример #14
0
        /// <summary>
        ///     Raises an event in the specified orchestration instance, which eventually causes the OnEvent() method in the
        ///     orchestration to fire.
        /// </summary>
        /// <param name="orchestrationInstance">Instance in which to raise the event</param>
        /// <param name="eventName">Name of the event</param>
        /// <param name="eventData">Data for the event</param>
        public async Task RaiseEventAsync(OrchestrationInstance orchestrationInstance, string eventName,
            object eventData)
        {
            if (orchestrationInstance == null || string.IsNullOrWhiteSpace(orchestrationInstance.InstanceId))
            {
                throw new ArgumentException("orchestrationInstance");
            }

            string serializedInput = defaultConverter.Serialize(eventData);
            var taskMessage = new TaskMessage
            {
                OrchestrationInstance = orchestrationInstance,
                Event = new EventRaisedEvent(-1, serializedInput) {Name = eventName}
            };

            BrokeredMessage brokeredMessage = Utils.GetBrokeredMessageFromObject(taskMessage,
                settings.MessageCompressionSettings);
            brokeredMessage.SessionId = orchestrationInstance.InstanceId;

            MessageSender sender =
                await messagingFactory.CreateMessageSenderAsync(orchestratorEntityName).ConfigureAwait(false);
            await sender.SendAsync(brokeredMessage).ConfigureAwait(false);
            await sender.CloseAsync().ConfigureAwait(false);
        }
Пример #15
0
 /// <summary>
 ///     Raises an event in the specified orchestration instance, which eventually causes the OnEvent() method in the
 ///     orchestration to fire.
 /// </summary>
 /// <param name="orchestrationInstance">Instance in which to raise the event</param>
 /// <param name="eventName">Name of the event</param>
 /// <param name="eventData">Data for the event</param>
 public void RaiseEvent(OrchestrationInstance orchestrationInstance, string eventName, object eventData)
 {
     Utils.AsyncExceptionWrapper(() => RaiseEventAsync(orchestrationInstance, eventName, eventData).Wait());
 }
Пример #16
0
        /// <summary>
        ///     Create a new orchestration of the specified name and version
        /// </summary>
        /// <param name="name">Name of the orchestration as specified by the ObjectCreator</param>
        /// <param name="version">Name of the orchestration as specified by the ObjectCreator</param>
        /// <param name="instanceId">Instance id for the orchestration to be created, must be unique across the Task Hub</param>
        /// <param name="input">Input parameter to the specified TaskOrchestration</param>
        /// <param name="tags">Dictionary of key/value tags associated with this instance</param>
        /// <returns>OrchestrationInstance that represents the orchestration that was created</returns>
        public async Task<OrchestrationInstance> CreateOrchestrationInstanceAsync(string name, string version,
            string instanceId,
            object input, IDictionary<string, string> tags)
        {
            if (string.IsNullOrWhiteSpace(instanceId))
            {
                instanceId = Guid.NewGuid().ToString("N");
            }

            var orchestrationInstance = new OrchestrationInstance
            {
                InstanceId = instanceId,
                ExecutionId = Guid.NewGuid().ToString("N"),
            };

            string serializedInput = defaultConverter.Serialize(input);
            string serializedtags = tags != null ? defaultConverter.Serialize(tags) : null;

            var startedEvent = new ExecutionStartedEvent(-1, serializedInput)
            {
                Tags = serializedtags,
                Name = name,
                Version = version,
                OrchestrationInstance = orchestrationInstance
            };

            var taskMessage = new TaskMessage
            {
                OrchestrationInstance = orchestrationInstance,
                Event = startedEvent
            };

            BrokeredMessage brokeredMessage = Utils.GetBrokeredMessageFromObject(taskMessage,
                settings.MessageCompressionSettings);
            brokeredMessage.SessionId = instanceId;

            MessageSender sender =
                await messagingFactory.CreateMessageSenderAsync(orchestratorEntityName).ConfigureAwait(false);
            await sender.SendAsync(brokeredMessage).ConfigureAwait(false);
            await sender.CloseAsync().ConfigureAwait(false);

            return orchestrationInstance;
        }
Пример #17
0
 /// <summary>
 ///     Raises an event in the specified orchestration instance, which eventually causes the OnEvent() method in the
 ///     orchestration to fire.
 /// </summary>
 /// <param name="orchestrationInstance">Instance in which to raise the event</param>
 /// <param name="eventName">Name of the event</param>
 /// <param name="eventData">Data for the event</param>
 public void RaiseEvent(OrchestrationInstance orchestrationInstance, string eventName, object eventData)
 {
     Utils.AsyncExceptionWrapper(() => RaiseEventAsync(orchestrationInstance, eventName, eventData).Wait());
 }
Пример #18
0
 /// <summary>
 ///     Get a list of orchestration states from the instance storage table for the
 ///     most current execution (generation) of the specified instance.
 ///     Throws if an Azure Storage account was not specified in the constructor.
 /// </summary>
 /// <param name="instance">Instance</param>
 /// <returns>The OrchestrationState of the specified instanceId or null if not found</returns>
 public OrchestrationState GetOrchestrationState(OrchestrationInstance instance)
 {
     return Utils.AsyncExceptionWrapper(() => GetOrchestrationStateAsync(instance).Result);
 }
Пример #19
0
 /// <summary>
 ///     Forcefully terminate the specified orchestration instance
 /// </summary>
 /// <param name="orchestrationInstance">Instance to terminate</param>
 public Task TerminateInstanceAsync(OrchestrationInstance orchestrationInstance)
 {
     return(TerminateInstanceAsync(orchestrationInstance, string.Empty));
 }
Пример #20
0
 /// <summary>
 ///     Get a list of orchestration states from the instance storage table for the
 ///     most current execution (generation) of the specified instance.
 ///     Throws if an Azure Storage account was not specified in the constructor.
 /// </summary>
 /// <param name="instance">Instance</param>
 /// <returns>The OrchestrationState of the specified instanceId or null if not found</returns>
 public Task<OrchestrationState> GetOrchestrationStateAsync(OrchestrationInstance instance)
 {
     return GetOrchestrationStateAsync(instance.InstanceId, instance.ExecutionId);
 }
Пример #21
0
 /// <summary>
 ///     Get a list of orchestration states from the instance storage table for the
 ///     most current execution (generation) of the specified instance.
 ///     Throws if an Azure Storage account was not specified in the constructor.
 /// </summary>
 /// <param name="instance">Instance</param>
 /// <returns>The OrchestrationState of the specified instanceId or null if not found</returns>
 public OrchestrationState GetOrchestrationState(OrchestrationInstance instance)
 {
     return(Utils.AsyncExceptionWrapper(() => GetOrchestrationStateAsync(instance).Result));
 }
Пример #22
0
        // Orchestration History

        /// <summary>
        ///     Get a string dump of the execution history of the specified orchestration instance
        ///     specified execution (generation) of the specified instance.
        ///     Throws if an Azure Storage account was not specified in the constructor.
        /// </summary>
        /// <param name="instance">Instance</param>
        /// <returns>String with formatted JSON representing the execution history</returns>
        public string GetOrchestrationHistory(OrchestrationInstance instance)
        {
            return Utils.AsyncExceptionWrapper(() => GetOrchestrationHistoryAsync(instance).Result);
        }
Пример #23
0
        // Orchestration History

        /// <summary>
        ///     Get a string dump of the execution history of the specified orchestration instance
        ///     specified execution (generation) of the specified instance.
        ///     Throws if an Azure Storage account was not specified in the constructor.
        /// </summary>
        /// <param name="instance">Instance</param>
        /// <returns>String with formatted JSON representing the execution history</returns>
        public string GetOrchestrationHistory(OrchestrationInstance instance)
        {
            return(Utils.AsyncExceptionWrapper(() => GetOrchestrationHistoryAsync(instance).Result));
        }
Пример #24
0
        /// <summary>
        ///     Get a string dump of the execution history of the specified orchestration instance
        ///     specified execution (generation) of the specified instance.
        ///     Throws if an Azure Storage account was not specified in the constructor.
        /// </summary>
        /// <param name="instance">Instance</param>
        /// <returns>String with formatted JSON representing the execution history</returns>
        public async Task<string> GetOrchestrationHistoryAsync(OrchestrationInstance instance)
        {
            if (instance == null || string.IsNullOrEmpty(instance.InstanceId) ||
                string.IsNullOrEmpty(instance.ExecutionId))
            {
                throw new ArgumentNullException("instance");
            }

            ThrowIfInstanceStoreNotConfigured();

            IEnumerable<OrchestrationHistoryEventEntity> eventEntities =
                await
                    tableClient.ReadOrchestrationHistoryEventsAsync(instance.InstanceId, instance.ExecutionId)
                        .ConfigureAwait(false);
            var events = new List<HistoryEvent>(eventEntities
                .OrderBy(ee => ee.SequenceNumber)
                .Select(historyEventEntity => historyEventEntity.HistoryEvent));

            string history = JsonConvert.SerializeObject(
                events, Formatting.Indented, new JsonSerializerSettings
                {
                    TypeNameHandling = TypeNameHandling.Objects
                });
            return history;
        }
Пример #25
0
        public static bool WaitForInstance(TaskHubClient taskHubClient, OrchestrationInstance instance,
            int timeoutSeconds,
            bool waitForCompletion = true)
        {
            if (instance == null || string.IsNullOrWhiteSpace(instance.InstanceId))
            {
                throw new ArgumentException("instance");
            }

            int sleepForSeconds = 2;

            while (timeoutSeconds > 0)
            {
                OrchestrationState state = taskHubClient.GetOrchestrationState(instance.InstanceId);
                if (state == null || (waitForCompletion && state.OrchestrationStatus == OrchestrationStatus.Running))
                {
                    Thread.Sleep(sleepForSeconds*1000);
                    timeoutSeconds -= sleepForSeconds;
                }
                else
                {
                    // Session state deleted after completion
                    return true;
                }
            }

            return false;
        }
        protected override async Task OnProcessWorkItem(BrokeredMessage message)
        {
            Utils.CheckAndLogDeliveryCount(message, taskHubDescription.MaxTaskActivityDeliveryCount, this.orchestratorQueueName);

            Task renewTask = null;
            var  renewCancellationTokenSource = new CancellationTokenSource();

            try
            {
                TaskMessage taskMessage = await Utils.GetObjectFromBrokeredMessageAsync <TaskMessage>(message);

                OrchestrationInstance orchestrationInstance = taskMessage.OrchestrationInstance;
                if (orchestrationInstance == null || string.IsNullOrWhiteSpace(orchestrationInstance.InstanceId))
                {
                    throw TraceHelper.TraceException(TraceEventType.Error,
                                                     new InvalidOperationException("Message does not contain any OrchestrationInstance information"));
                }
                if (taskMessage.Event.EventType != EventType.TaskScheduled)
                {
                    throw TraceHelper.TraceException(TraceEventType.Critical,
                                                     new NotSupportedException("Activity worker does not support event of type: " +
                                                                               taskMessage.Event.EventType));
                }

                // call and get return message
                var          scheduledEvent = (TaskScheduledEvent)taskMessage.Event;
                TaskActivity taskActivity   = objectManager.GetObject(scheduledEvent.Name, scheduledEvent.Version);
                if (taskActivity == null)
                {
                    throw new TypeMissingException("TaskActivity " + scheduledEvent.Name + " version " +
                                                   scheduledEvent.Version + " was not found");
                }

                renewTask = Task.Factory.StartNew(() => RenewUntil(message, renewCancellationTokenSource.Token));

                // TODO : pass workflow instance data
                var          context        = new TaskContext(taskMessage.OrchestrationInstance);
                HistoryEvent eventToRespond = null;

                try
                {
                    string output = await taskActivity.RunAsync(context, scheduledEvent.Input);

                    eventToRespond = new TaskCompletedEvent(-1, scheduledEvent.EventId, output);
                }
                catch (TaskFailureException e)
                {
                    TraceHelper.TraceExceptionInstance(TraceEventType.Error, taskMessage.OrchestrationInstance, e);
                    string details = IncludeDetails ? e.Details : null;
                    eventToRespond = new TaskFailedEvent(-1, scheduledEvent.EventId, e.Message, details);
                }
                catch (Exception e)
                {
                    TraceHelper.TraceExceptionInstance(TraceEventType.Error, taskMessage.OrchestrationInstance, e);
                    string details = IncludeDetails
                        ? string.Format("Unhandled exception while executing task: {0}\n\t{1}", e, e.StackTrace)
                        : null;
                    eventToRespond = new TaskFailedEvent(-1, scheduledEvent.EventId, e.Message, details);
                }

                var responseTaskMessage = new TaskMessage();
                responseTaskMessage.Event = eventToRespond;
                responseTaskMessage.OrchestrationInstance = orchestrationInstance;

                BrokeredMessage responseMessage = Utils.GetBrokeredMessageFromObject(responseTaskMessage,
                                                                                     settings.MessageCompressionSettings,
                                                                                     orchestrationInstance, "Response for " + message.MessageId);
                responseMessage.SessionId = orchestrationInstance.InstanceId;

                using (var ts = new TransactionScope())
                {
                    workerQueueClient.Complete(message.LockToken);
                    deciderSender.Send(responseMessage);
                    ts.Complete();
                }
            }
            finally
            {
                if (renewTask != null)
                {
                    renewCancellationTokenSource.Cancel();
                    renewTask.Wait();
                }
            }
        }