public override void Execute(EventExecutionContext context, CommandExecutionHandle handle) { var director = directorReference.Resolve(context.ReferenceResolver); if (!director) { throw new NullReferenceException(); } switch (control) { case ControlType.Resume: director.Resume(); break; case ControlType.Pause: director.Pause(); break; case ControlType.Stop: director.Stop(); break; default: throw new ArgumentOutOfRangeException(); } handle.Complete(); }
public async Task <EventExecutionResult> Execute(EventExecutionContext eventExecutionContext, CancellationToken cancellationToken = default) { var remoteCode = Code.GetRemoteCode(); var remoteExecutionState = eventExecutionContext.WorkflowContext.CreateRemoteExecutionState( eventExecutionContext.EventConfiguration.Parameters, remoteCode); var eventRequestWorkflowMessage = new EventRequestWorkflowMessage(eventExecutionContext.WorkflowContext.WorkflowConfiguration.Id, eventExecutionContext.WorkflowContext.WorkflowInstance.Id, remoteCode, remoteExecutionState); var workflowConfiguration = eventExecutionContext.WorkflowContext.WorkflowConfiguration; var endpointConfiguration = workflowConfiguration.FindEndpointConfiguration(Code); Log.Verbose("Sending event request message [{code}::{messageId}] to {endpoint} [{workflowInstanceId}]", Code, eventRequestWorkflowMessage.WorkflowMessageId, endpointConfiguration.Address, eventExecutionContext.WorkflowContext.WorkflowInstance.Id); var messageTransport = eventExecutionContext.WorkflowContext .WorkflowMessageTransportFactoryProvider.CreateMessageTransportFactory(endpointConfiguration.Type) .CreateMessageTransport(endpointConfiguration.Address); var responseWorkflowMessage = await messageTransport.Request <IEventRequestWorkflowMessage, IEventResponseWorkflowMessage>( endpointConfiguration, eventRequestWorkflowMessage, cancellationToken).ConfigureAwait(false); Log.Verbose("Received event response message [{messageId}] from {endpoint} [{workflowInstanceId}]", eventRequestWorkflowMessage.WorkflowMessageId, endpointConfiguration.Address, eventExecutionContext.WorkflowContext.WorkflowInstance.Id); // merge state changes made by remote event handler during execution eventExecutionContext.WorkflowContext.MergeRemoteExecutionState(responseWorkflowMessage.State); return(responseWorkflowMessage.EventExecutionResult); }
private async UniTaskVoid ExecuteAsync(EventExecutionContext context, CommandExecutionHandle handle) { var timelineModule = context.GetModule <TimelineModule>(); if (!timelineModule) { throw new NullReferenceException(); } var cs = new UniTaskCompletionSource(); Action <SignalAsset> onSignalNotify = signalAsset => { if (signalAsset == target) { cs.TrySetResult(); } }; timelineModule.OnSignalNotify += onSignalNotify; await PlayNestedCommands(context); await cs.Task; timelineModule.OnSignalNotify -= onSignalNotify; handle.Complete(); }
public void Play(T option) { if (!option.Ready(ScriptVariablesDatabase)) { throw new ArgumentException(); } EnsureInitialized(); if (IsPlaying) { throw new InvalidOperationException("EventScriptPlayerは別のイベントを再生中です。"); } var context = new EventExecutionContext(this); CurrentContext = context; Debug.Log("EventScriptPlayer: Start."); context.Play(option.Script, () => { Debug.Log("EventScriptPlayer: End."); OnCompleteEvent(context, option); CurrentContext = null; }, (exception) => { Debug.Log("EventScriptPlayer: Error."); CurrentContext = null; OnErrorEvent(context, option); //TODO: Modulesに対するエラー通知 }, option.RuntimeReferenceHost, option.EventVariables, option.TemporaryVariables, () => OnPlayEvent(context, option)); }
public override void Execute(EventExecutionContext context, CommandExecutionHandle handle) { var dialog = context.GetModule <DialogModule>(); if (dialog == default) { context.RaiseError(new ScriptExecutionException("DialogModuleが登録されていません。")); return; } if (dialog.CurrentProvider != null) { var providerName = dialog.CurrentProvider.ProviderName; dialog.Close(() => { var script = new EventScript(); script.CommandList = commandList; script.WaitForAllCommands = true; context.InsertInherit(script, () => { dialog.Open(providerName, handle.Complete); }); }); } else { var script = new EventScript(); script.CommandList = commandList; script.WaitForAllCommands = true; context.InsertInherit(script, handle.Complete); } }
public async Task <EventExecutionResult> Execute(EventExecutionContext eventExecutionContext, CancellationToken cancellationToken = default) { var workflowContext = eventExecutionContext.WorkflowContext; if (ScriptType != ScriptTypeConfiguration.CSharp) { throw new WorkflowException(string.Format(CultureInfo.InvariantCulture, "CSharpScriptEventHandler can execute only CSharp scripts but [{0}] has been provided for workflow [ID={1:D}]", ScriptType, eventExecutionContext.WorkflowContext.WorkflowInstance.Id)); } var scriptKey = $"EVENTHANDLER::{workflowContext.WorkflowConfiguration.Id:D}::{Code}::{Script.GetHashCode():D}"; Assembly[] assemblies = null; var entity = workflowContext.WorkflowInstance.Entity; if (null != entity) { assemblies = new[] { entity.GetType().Assembly }; } Exception exception; try { var cSharpScript = WorkflowEngine.ScriptingEngine.Value.GetScript <EventHandlerExecutionContextGlobals>(scriptKey, Script, assemblies); var scriptState = await cSharpScript.RunAsync(new EventHandlerExecutionContextGlobals { context = eventExecutionContext, entity = entity, state = eventExecutionContext.WorkflowContext.WorkflowExecutionState, workflowRuntime = workflowContext.WorkflowEngine, cancellationToken = cancellationToken }, cancellationToken).ConfigureAwait(false); // if event handler returned "FALSE" --> do not move workflow instance from "AwaitingEvent" if (null != scriptState.ReturnValue && scriptState.ReturnValue is bool boolean && !boolean) { return(new EventExecutionResult(EventExecutionStatus.KeepWaiting)); } if (null == scriptState.Exception) { return(new EventExecutionResult(EventExecutionStatus.Completed)); } exception = scriptState.Exception; } catch (Exception ex) { exception = ex; } Log.Error(exception, "An error has occurred during execution of scripted event [{state}, {code}] for {workflowInstanceId}]", eventExecutionContext.StateEventConfiguration.Code, eventExecutionContext.EventConfiguration.Code, eventExecutionContext.WorkflowContext.WorkflowInstance.Id); return(new EventExecutionResult(EventExecutionStatus.Failed)); }
public Task <EventExecutionResult> Execute(EventExecutionContext eventExecutionContext, CancellationToken cancellationToken = default) { if (string.Equals(eventExecutionContext.WorkflowContext.WorkflowInstance.CurrentStateCode, "process", StringComparison.OrdinalIgnoreCase)) { throw new Exception(); } return(Task.FromResult(new EventExecutionResult(EventExecutionStatus.Completed))); }
private UniTask PlayNestedCommands(EventExecutionContext context) { var cs = new UniTaskCompletionSource(); var script = new EventScript(); script.CommandList = nestedCommands; script.WaitForAllCommands = false; context.InsertInherit(script, () => { cs.TrySetResult(); }); return(cs.Task); }
public override void Execute(EventExecutionContext context, CommandExecutionHandle handle) { var dialog = context.GetModule <DialogModule>(); if (dialog == default) { context.RaiseError(new ScriptExecutionException("DialogModuleが登録されていません。")); return; } dialog.Cut.Show(sprite, duration, updateMode, handle.Complete); }
public override void Execute(EventExecutionContext context, CommandExecutionHandle handle) { var dialog = context.GetModule <DialogModule>(); if (dialog == default) { context.RaiseError(new ScriptExecutionException("DialogSessionが登録されていません。")); return; } dialog.ShowMessage(settings, () => { handle.Complete(); }); }
public override void Execute(EventExecutionContext context, CommandExecutionHandle handle) { Debug.Log("SampleEventCommand3: ネストされたイベントを実行します。"); var script = new EventScript(); script.WaitForAllCommands = false; script.CommandList = commandList; context.InsertInherit(script, () => { Debug.Log("SampleEventCommand3: ネストの終了。"); handle.Complete(); }); }
public override void Execute(EventExecutionContext context, CommandExecutionHandle handle) { var obj = targetGameObject.Resolve(context.ReferenceResolver); if (obj) { Debug.Log($"シーン参照に成功しました。: {obj.name}", obj); } else { Debug.Log($"シーン参照に失敗しました。"); } handle.Complete(); }
public void SetUp() { _workflowInstance = new Mock <IWorkflowInstance>(); _runtimeWorkflowEngine = new Mock <IRuntimeWorkflowEngine>(); _endpointConfiguration = new Mock <IEndpointConfiguration>(); _workflowMessageTransport = new Mock <IWorkflowMessageTransport>(); _workflowMessageTransportFactory = new Mock <IWorkflowMessageTransportFactory>(); _workflowMessageTransportFactoryProvider = new Mock <IWorkflowMessageTransportFactoryProvider>(); _workflowEngineBuilder = new WorkflowEngineBuilder().WithMessageTransportFactoryProvider(_workflowMessageTransportFactoryProvider.Object); _endpointConfiguration.Setup(f => f.Code).Returns("rabbit.mq"); _endpointConfiguration.Setup(f => f.Address).Returns(new Uri("rabbitmq://localhost/address")); var workflowId = Guid.NewGuid(); _workflowInstance.Setup(f => f.Id).Returns(workflowId); _workflowConfiguration = new WorkflowConfiguration(workflowId, "unit.test", "unit.test", "Unit Test", new Version(0, 0, 1)) { RuntimeConfiguration = new WorkflowRuntimeConfiguration(workflowId, "unit.test", "unit.test") { EndpointConfiguration = _endpointConfiguration.Object, EndpointConfigurations = new[] { new KeyValuePair <string, IEndpointConfiguration>("remote.*", _endpointConfiguration.Object) } } }; _eventResponseWorkflowMessage = new EventResponseWorkflowMessage { EventExecutionResult = new EventExecutionResult(EventExecutionStatus.Completed) }; _workflowMessageTransport .Setup(f => f.Request <IEventRequestWorkflowMessage, IEventResponseWorkflowMessage>( It.IsAny <IEndpointConfiguration>(), It.IsAny <IEventRequestWorkflowMessage>(), It.IsAny <CancellationToken>())) .Returns <IEndpointConfiguration, IWorkflowMessage, CancellationToken>((epc, wm, ct) => Task.FromResult(_eventResponseWorkflowMessage)); _workflowMessageTransportFactoryProvider .Setup(f => f.CreateMessageTransportFactory(It.IsAny <EndpointConfigurationType>())) .Returns <EndpointConfigurationType>(uri => _workflowMessageTransportFactory.Object); _workflowMessageTransportFactory .Setup(f => f.CreateMessageTransport(It.IsAny <Uri>())) .Returns <Uri>(uri => _workflowMessageTransport.Object); _event = new StatefulEvent("remote.{sign-event01}", workflowId, new JsonState()); _workflowContext = new WorkflowContext(_runtimeWorkflowEngine.Object, _workflowEngineBuilder, _workflowInstance.Object, _workflowConfiguration); _eventExecutionContext = new EventExecutionContext(_workflowContext, _event, new EventConfiguration(EventTypeConfiguration.Application, _event.Code, string.Empty), new StateEventConfiguration()); }
public override void Execute(EventExecutionContext context, CommandExecutionHandle handle) { var dialog = context.GetModule <DialogModule>(); if (dialog == default) { context.RaiseError(new ScriptExecutionException("DialogSessionが登録されていません。")); return; } string[] items = bifurcations.Select(b => b.Label).ToArray(); var settings = new DialogShowMenuSettings(items); dialog.ShowMenu(settings, (index) => { var script = new EventScript(); script.WaitForAllCommands = false; script.CommandList = bifurcations[index].CommandList; context.InsertInherit(script, handle.Complete); }); }
public override void Execute(EventExecutionContext context, CommandExecutionHandle handle) { var dialog = context.GetModule <DialogModule>(); if (dialog == default) { context.RaiseError(new ScriptExecutionException("DialogModuleが登録されていません。")); return; } dialog.Fade.In(inDuration, () => { var script = new EventScript() { CommandList = nestedCommands, WaitForAllCommands = true }; context.InsertInherit(script, () => { dialog.Fade.Out(outDuration, handle.Complete); }); }); }
private async UniTaskVoid ExecuteAsync(EventExecutionContext context, CommandExecutionHandle handle) { var timelineModule = context.GetModule <TimelineModule>(); if (!timelineModule) { throw new NullReferenceException(); } var director = directorReference.Resolve(context.ReferenceResolver); if (!director) { throw new NullReferenceException(); } var timelinePlaying = PlayTimeline(director, timelineModule); await PlayNestedCommands(context); await timelinePlaying; handle.Complete(); }
public Task <EventExecutionResult> Execute(EventExecutionContext eventExecutionContext, CancellationToken cancellationToken = default) { return(Task.FromResult(new EventExecutionResult(EventExecutionStatus.Completed))); }
/// <summary> /// イベントの再生が正常に終わったときに呼ばれる。 /// </summary> /// <param name="context"></param> protected virtual void OnCompleteEvent(EventExecutionContext context, T option) { }
/// <summary> /// イベントの再生がエラーで終了したときに呼ばれる。 /// </summary> /// <param name="context"></param> protected virtual void OnErrorEvent(EventExecutionContext context, T option) { }
public override void Execute(EventExecutionContext context, CommandExecutionHandle handle) { ExecuteAsync(context, handle).Forget(); }
private async Task <WorkflowProcessingResult> ProcessEventInternal(Guid workflowId, IEvent @event, CancellationToken cancellationToken) { var isHierarchicalEvent = @event.IsHierarchicalEvent(); var workflowConfiguration = await GetWorkflowConfiguration(workflowId, cancellationToken).ConfigureAwait(false); var eventConfiguration = workflowConfiguration.GetEventConfigurationByCode(@event.Code); if (null == eventConfiguration && isHierarchicalEvent) { if (!Enum.TryParse(@event.Code, out EventTypeConfiguration eventTypeConfiguration)) { throw new WorkflowException(string.Format(CultureInfo.InvariantCulture, "System event must have code of EventType but following value have been encountered [{0}] for workflow [{1}]", @event.Code, workflowConfiguration.Code)); } eventConfiguration = workflowConfiguration.GetEventConfigurationByType(eventTypeConfiguration); } if (null == eventConfiguration) { throw new WorkflowException($"Event with code [{@event.Code}] was not found in workflow [{workflowConfiguration.Code}]"); } WorkflowContext workflowContext; IWorkflowInstance workflowInstance; StateConfiguration stateConfiguration; StateEventConfiguration stateEventConfiguration; if (eventConfiguration.Type == EventTypeConfiguration.Initial || eventConfiguration.Type == EventTypeConfiguration.ParentToNestedInitial) { stateConfiguration = workflowConfiguration.GetStateConfigurationByType(StateTypeConfiguration.Initial); stateEventConfiguration = stateConfiguration.Events .Single(se => string.Equals(se.Code, eventConfiguration.Code, StringComparison.OrdinalIgnoreCase)); var id = Guid.NewGuid(); var workflowInstanceLock = CreateWorkflowInstanceLock(workflowConfiguration); workflowInstance = new WorkflowInstance(workflowId, id, @event.GetRootWorkflowInstanceIdOrUseCurrent(id), @event.GetParentWorkflowInstanceIdOrUseCurrent(id), @event.GetDomainEntityTypeOrNull(), @event.GetDomainEntityIdOrNull(), workflowInstanceLock, @event.GetDomainEntityOrNull()) { Created = DateTime.UtcNow, CurrentStateCode = stateConfiguration.Code, CurrentStateProgress = StateExecutionProgress.AwaitingEvent }; await TryGetDomainEntity(workflowConfiguration, workflowInstance, cancellationToken).ConfigureAwait(false); await SaveWorkflowInstance(workflowInstance, cancellationToken).ConfigureAwait(false); } else { var hierarchicalEvent = @event as IHierarchicalEvent; if (null != hierarchicalEvent) { // for system events: // 1. intended to be used inside activities only // 2. lock on a root workflow instance should have been obtained earlier workflowInstance = hierarchicalEvent.TargetWorkflowInstance ?? await GetWorkflowInstanceWithNoLock(@event.WorkflowInstanceId, cancellationToken) .ConfigureAwait(false); Guard.ArgumentNotNull(workflowInstance, nameof(workflowInstance)); } else { // for other events: we need to obtain a lock on a root workflow instance workflowInstance = await GetWorkflowInstanceWithLock(@event.WorkflowInstanceId, cancellationToken).ConfigureAwait(false); Guard.ArgumentNotNull(workflowInstance, nameof(workflowInstance)); } stateConfiguration = workflowConfiguration.GetStateConfigurationByCode(workflowInstance.CurrentStateCode); Guard.ArgumentNotNull(stateConfiguration, nameof(stateConfiguration)); if (null != hierarchicalEvent) { // break cycling if (stateConfiguration.Type == StateTypeConfiguration.Failed && eventConfiguration.Type.IsFailed()) { return(new WorkflowProcessingResult(workflowInstance)); } if (hierarchicalEvent.HierarchyEventType == WorkflowHierarchyEventType.Failed) { Log.Warning("Received event {code} into {workflowInstanceId}]", @event.Code, workflowInstance.Id); return(await TransitionToFailedStatus(@event, workflowInstance, workflowConfiguration, cancellationToken).ConfigureAwait(false)); } } // workflow instance must be awaiting for the event otherwise move it to failed if (workflowInstance.CurrentStateProgress != StateExecutionProgress.AwaitingEvent) { Log.Error("Can not process event {code} for {workflowInstanceId} because workflow instance is not in [{subState}], it is in [{state}] and [{stateProgress}]", @event.Code, workflowInstance.Id, StateExecutionProgress.AwaitingEvent, workflowInstance.CurrentStateCode, workflowInstance.CurrentStateProgress); return(await TransitionToFailedStatus(@event, workflowInstance, workflowConfiguration, cancellationToken).ConfigureAwait(false)); } if (null == stateConfiguration) { Log.Error("{workflowInstanceId} is in the {state} which does not belong to {workflow}", workflowInstance.Id, workflowInstance.CurrentStateCode, workflowConfiguration.Code); return(await TransitionToFailedStatus(@event, workflowInstance, workflowConfiguration, cancellationToken).ConfigureAwait(false)); } if (isHierarchicalEvent) { stateEventConfiguration = stateConfiguration.Events .SingleOrDefault(e => string.Equals(e.Code, @event.Code, StringComparison.OrdinalIgnoreCase)); } else { if (!stateConfiguration.Events.Any(e => string.Equals(e.Code, @event.Code, StringComparison.OrdinalIgnoreCase))) { Log.Error("{workflowInstanceId} is in the {state} which does not accept {event}", workflowInstance.Id, stateConfiguration.Code, @event.Code); return(await TransitionToFailedStatus(@event, workflowInstance, workflowConfiguration, cancellationToken).ConfigureAwait(false)); } stateEventConfiguration = stateConfiguration.Events.Single(e => string.Equals(e.Code, @event.Code, StringComparison.OrdinalIgnoreCase)); } workflowInstance.Entity = @event.GetDomainEntityOrNull(); await TryGetDomainEntity(workflowConfiguration, workflowInstance, cancellationToken).ConfigureAwait(false); } workflowContext = new WorkflowContext(this, WorkflowEngineBuilder, workflowInstance, workflowConfiguration, @event.GetEventStateOrDefault()); var eventExecutionContext = new EventExecutionContext(workflowContext, @event, eventConfiguration, stateEventConfiguration); var eventExecutionResult = await _eventProcessorLazy.Value.Process(eventExecutionContext, cancellationToken).ConfigureAwait(false); switch (eventExecutionResult.Status) { case EventExecutionStatus.KeepWaiting: { Log.Information("After processing event [{code}] the {workflowInstanceId} keeps waiting in for another event of {nextCode}", @event.Code, workflowInstance.Id, @event.Code); break; } case EventExecutionStatus.Failed: case EventExecutionStatus.FailedNoRetry: { Log.Error("An error has occurred during processing event [{code}] for {workflowInstanceId}]", @event.Code, workflowInstance.Id); await TransitionToState(workflowContext, workflowConfiguration.GetFailedStateConfiguration(), null, cancellationToken).ConfigureAwait(false); break; } default: { workflowContext.WorkflowInstance.CurrentStateProgress = StateExecutionProgress.AfterEventProcessed; await ProcessState(workflowContext, stateConfiguration, cancellationToken).ConfigureAwait(false); break; } } return(new WorkflowProcessingResult(workflowInstance, workflowContext.WorkflowExecutionState)); }
public override void Execute(EventExecutionContext context, CommandExecutionHandle handle) { Debug.Log("SampleEventCommand1 executed!"); handle.Complete(); }