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()); }
/// <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); }
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; }
public static string PrintHistory(TaskHubClient taskHubClient, OrchestrationInstance instance) { return taskHubClient.GetOrchestrationHistory(instance); }
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. } } } }
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(); } }
/// <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)); }
/// <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()); }
/// <summary> /// Forcefully terminate the specified orchestration instance /// </summary> /// <param name="orchestrationInstance">Instance to terminate</param> public void TerminateInstance(OrchestrationInstance orchestrationInstance) { TerminateInstance(orchestrationInstance, string.Empty); }
/// <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); }
/// <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); }
/// <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); }
/// <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()); }
/// <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; }
/// <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); }
/// <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)); }
/// <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); }
/// <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)); }
// 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); }
// 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)); }
/// <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; }
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(); } } }