Beispiel #1
0
 private static void AttemptCleanup(Database db, Execution execution, WorkflowObj workflow, List <History> decisions)
 {
     if (ExState.Create(execution.ExecutionState.State) == ExState.Cleanup)
     {
         StopWorkflow(execution, decisions);
         return;
     }
     try
     {
         var cleanupStartTask = workflow.Tasks.SingleOrDefault(t => t.ActivityName == "cleanup");
         if (cleanupStartTask == null)
         {
             StopWorkflow(execution, decisions);
             return;
         }
         var cleanupTaskId = cleanupStartTask.Outflows.Single(o => o.Name == "Out").Target;
         var cleanupTask   = workflow.Tasks.Single(t => t.TaskId == cleanupTaskId);
         decisions.Add(new WorkflowCleanupStartedEvent());
         CreateTaskScheduledEvent(db, execution, cleanupTask, decisions);
     }
     catch (Exception ex)
     {
         log.Error("Exception thrown from cleanup", ex);
         StopWorkflow(execution, decisions);
     }
 }
Beispiel #2
0
        public C Create(Context data)
        {
            ExState exState = ContextToExState(data);
            InState inState = ContextToInState(data);

            return(new C(inState, exState));
        }
Beispiel #3
0
        // Large footprint

        public void Op(ExState anExState)
        {
            // Uses both intrinsic and
            // extrinsic state
        }
Beispiel #4
0
        public bool ExUpdate(float ctime, float bp, ref bool[] button, ref bool[] released, ref MarkManager.EffectType check, bool auto, ref int soundtype, MarkManager.EvaluateEffectHandler effectcallback)
        {
            bool ret = false;

            lasttime = ctime;
            //base.Update(ctime, bp, ref button, ref check, auto, ref soundtype);
            if (!auto)
            {
                if (exstate == ExState.waitingpress)
                {
                    if (button[(int)ButtonType])
                    {
                        int a = evaluate(this.time, ctime - adjustgaptime);
                        if (a > 1)
                        {
                            button[(int)ButtonType] = false;
                        }
                        switch (a)
                        {
                        // if more than safe,ok
                        case 5:
                            check   = MarkManager.EffectType.Cool;
                            exstate = ExState.pressok;
                            break;

                        case 4:
                            check   = MarkManager.EffectType.Fine;
                            exstate = ExState.pressok;
                            break;

                        case 3:
                            check   = MarkManager.EffectType.Safe;
                            state   = State.safe;
                            exstate = ExState.released;
                            ret     = true;
                            break;

                        case 2:
                            check   = MarkManager.EffectType.Sad;
                            state   = State.sad;
                            exstate = ExState.released;
                            ret     = true;
                            break;

                        case 1:
                            check   = MarkManager.EffectType.Worst;
                            state   = State.worst;
                            exstate = ExState.released;
                            ret     = true;
                            break;

                        case 0:
                            break;
                        }
                        if (a != 0)
                        {
                            hidden         = false;
                            pos1           = new Vector2[40];
                            pos2           = new Vector2[40];
                            iVerticesCount = 0;
                        }
                        if (AC && (check == MarkManager.EffectType.Cool || check == MarkManager.EffectType.Fine))
                        {
                            state = State.cool;
                            effectcallback.Invoke(MarkManager.EffectType.Cool, Position);
                            hidden = true;
                        }
                    }
                }
                else if (exstate == ExState.pressok)
                {
                    if (AC)
                    {
                        if (released[(int)ButtonType])
                        {
                            check = MarkManager.EffectType.PressReleased;
                            ret   = true;
                        }
                        else
                        {
                            check = MarkManager.EffectType.Pressing;
                        }
                    }
                    else
                    {
                        if (released[(int)ButtonType])
                        {
                            released[(int)ButtonType] = false;
                            int a = evaluate(this.endtime, ctime - adjustgaptime);
                            switch (a)
                            {
                            // final evaluate
                            case 5:
                                check = MarkManager.EffectType.Cool;
                                state = State.cool;
                                effectcallback.Invoke(MarkManager.EffectType.Cool, Position);
                                exstate = ExState.released;
                                ret     = true;
                                break;

                            case 4:
                                check = MarkManager.EffectType.Fine;
                                state = State.fine;
                                effectcallback.Invoke(MarkManager.EffectType.Fine, Position);
                                exstate = ExState.released;
                                ret     = true;
                                break;

                            case 3:
                                check = MarkManager.EffectType.Safe;
                                state = State.safe;
                                effectcallback.Invoke(MarkManager.EffectType.Safe, Position);
                                exstate = ExState.released;
                                ret     = true;
                                break;

                            case 2:
                                check = MarkManager.EffectType.Sad;
                                state = State.sad;
                                effectcallback.Invoke(MarkManager.EffectType.Sad, Position);
                                exstate = ExState.released;
                                ret     = true;
                                break;

                            case 1:
                                check   = MarkManager.EffectType.Worst;
                                state   = State.worst;
                                exstate = ExState.released;
                                ret     = true;
                                break;

                            case 0:
                                check   = MarkManager.EffectType.Worst;
                                state   = State.worst;
                                exstate = ExState.released;
                                ret     = true;
                                break;
                            }
                            if (state >= State.cool && state <= State.sad)
                            {
                                //離したとき用の音
                                soundtype = (int)ButtonType;
                            }
                        }
                    }
                }
                if (exstate == ExState.waitingpress)
                {
                    if (ctime - this.time >= eval[3])
                    {
                        check = MarkManager.EffectType.Worst;
                        ret   = true;
                    }
                }
                else if (exstate == ExState.pressok)
                {
                    if (!AC)
                    {
                        if (ctime - this.endtime >= eval[3])
                        {
                            check = MarkManager.EffectType.Worst;
                            ret   = true;
                        }
                    }
                }
            }
            else
            {
                //when auto
                if (exstate == ExState.waitingpress)
                {
                    if (ctime - this.time >= -autowidth)
                    {
                        check     = MarkManager.EffectType.Cool;
                        exstate   = ExState.pressok;
                        soundtype = (int)ButtonType;
                        if (AC)
                        {
                            state = State.cool;
                            effectcallback.Invoke(MarkManager.EffectType.Cool, Position);
                            hidden = true;
                        }
                        else
                        {
                            hidden = false;
                        }
                        pos1           = new Vector2[40];
                        pos2           = new Vector2[40];
                        iVerticesCount = 0;
                    }
                }
                else if (exstate == ExState.pressok)
                {
                    if (AC)
                    {
                        check = MarkManager.EffectType.Pressing;
                    }
                    else
                    {
                        if (ctime - this.endtime >= -autowidth)
                        {
                            check     = MarkManager.EffectType.Cool;
                            exstate   = ExState.released;
                            soundtype = (int)ButtonType + 10;
                            state     = State.cool;
                            effectcallback.Invoke(MarkManager.EffectType.Cool, Position);
                            hidden = false;
                            ret    = true;
                        }
                    }
                }
            }
            if (state < State.cool)
            {
                float scale = (float)bp / defaultbpm;
                if (hidden)
                {
                    if (this.time - ctime <= 2 / scale)
                    {
                        if (dState == DisplayState.Normal || dState == DisplayState.Hidden)
                        {
                            effectcallback.Invoke(MarkManager.EffectType.Appear, Position);
                            hidden = false;
                        }
                    }
                    if (this.time - ctime <= 0.5f / scale)
                    {
                        if (dState == DisplayState.Sudden)
                        {
                            effectcallback.Invoke(MarkManager.EffectType.Appear, Position);
                            hidden = false;
                        }
                    }
                    if (this.time - ctime <= 0.25f / scale)
                    {
                        if (dState == DisplayState.Hidden && exstate == ExState.waitingpress)
                        {
                            effectcallback.Invoke(MarkManager.EffectType.Appear, Position);
                            hidden = true;
                        }
                    }
                    if (this.endtime - ctime <= 0.25f / scale)
                    {
                        if (dState == DisplayState.Hidden)
                        {
                            effectcallback.Invoke(MarkManager.EffectType.Appear, Position);
                            hidden = true;
                        }
                    }
                }
                if (state == State.appearing && !hidden)
                {
                    float sx = mark.Scale.X + 0.05f;
                    mark.Scale      = new Vector2(sx, sx);
                    outcircle.Scale = new Vector2(sx, sx);
                    outjiku.Scale   = new Vector2(sx, sx);
                    hold.Scale      = new Vector2(sx, sx);
                    if (mark.Scale.X > 1.2f)
                    {
                        mark.Scale      = new Vector2(1, 1);
                        outcircle.Scale = new Vector2(1, 1);
                        outjiku.Scale   = new Vector2(1, 1);
                        hold.Scale      = new Vector2(1, 1);
                        state           = State.moving;
                    }
                }
                CaliculateColorPosition(ctime, bp);
                jiku.Rotation = -1 * (float)Math.PI * (this.time - ctime) * scale;
                if (jiku.Rotation >= 0)
                {
                    jiku.Rotation = 0;
                }
                outjiku.Rotation = -2 * (float)Math.PI * (this.time - ctime) / length;
            }
            mark.Update();
            markc.Update();
            jiku.Update();
            outcircle.Update();
            outjiku.Update();
            hold.Update();
            return(ret);
        }
Beispiel #5
0
 public C(InState inState, ExState exState)
 {
     TheInState = inState;
     TheExState = exState;
 }
Beispiel #6
0
        /// <summary>
        /// Change the current execution state
        /// POSTed json object:
        /// {"command": cmd}
        /// where cmd is a string and one of
        /// "run", "pause", "cancel" or "stop".
        /// </summary>
        public ExecutionStateModule()
        {
            log = LogManager.GetLogger(typeof(ExecutionStateModule));
            History history = null;

            Post["/executionstate/{executionid}"] = parameters =>
            {
                ExState newState;
                string  command;

                using (var reader = new StreamReader(Request.Body))
                {
                    var     json = reader.ReadToEnd();
                    JObject obj;
                    try
                    {
                        obj = JObject.Parse(json);
                    }
                    catch
                    {
                        var response = new Response();
                        response.StatusCode   = HttpStatusCode.BadRequest;
                        response.ReasonPhrase = "Invalid JSON";
                        return(response);
                    }
                    command = ((string)obj.SelectToken("$.state")).ToLower();

                    switch (command)
                    {
                    case "run":
                        history  = new WorkflowExecutionResumedEvent {
                        };
                        newState = ExState.Running;
                        break;

                    case "pause":
                        history  = new WorkflowExecutionPausedEvent {
                        };
                        newState = ExState.Paused;
                        break;

                    case "cancel":
                        history  = new WorkflowExecutionCancelledEvent {
                        };
                        newState = ExState.Running;
                        break;

                    case "stop":
                        history  = new WorkflowStoppedEvent {
                        };
                        newState = ExState.Stopped;
                        break;

                    default:
                        return(new Response().WithStatusCode(HttpStatusCode.BadRequest));
                    }
                }
                Guid executionId;
                if (!Guid.TryParse(parameters.executionid, out executionId))
                {
                    return(new Response().WithStatusCode(HttpStatusCode.BadRequest));
                }

                using (var db = new Database())
                {
                    var execution      = db.Executions.SingleOrDefault(e => e.ExecutionId == executionId);
                    var executionState = db.ExecutionStates.SingleOrDefault(st => st.ExecutionId == executionId);

                    if (execution == null || executionState == null)
                    {
                        return new Response {
                                   StatusCode = HttpStatusCode.NotFound
                        }
                    }
                    ;

                    var state = ExState.Create(executionState.State);

                    // Do not change terminal states and ignore if newState is the current state
                    if (state == ExState.Stopped ||                                         // Cannot change STOPPED state
                        (state == ExState.Cleanup && newState != ExState.Stopped) ||        // Can only go to STOPPED from CLEANUP
                        (state == newState && command != "cancel"))                         // No state change and not cancelling
                    {
                        return(((Response)state.Json).WithContentType("application/json"));
                    }

                    Database.InsertHistory(execution, history);

                    if (state == newState)
                    {
                        return(((Response)newState.Json).WithContentType("application/json"));
                    }

                    // Now update the execution state and retry upon failure
                    executionState.State = newState;

                    int i;
                    for (i = 0; i < DB_RETRIES; i++)
                    {
                        try
                        {
                            db.SubmitChanges();
                        }
                        catch (ChangeConflictException)
                        {
                            // Surely there can be, at most, only one conflict on the executionState
                            foreach (var conflict in db.ChangeConflicts.Where(c => c.Object == executionState))
                            {
                                // Conflict must be the state value
                                var mc = conflict.MemberConflicts.Single();

                                // Should never happen
                                if (mc.Member.Name != "State")
                                {
                                    log.Error($"ExecutionState update conflict member name is {mc.Member.Name}");
                                    throw new ApplicationException($"ExecutionState update conflict member name is {mc.Member.Name}");
                                }

                                var dbState = ExState.Create((string)mc.DatabaseValue);

                                // The desired state was set elsewhere, so leave it
                                if (dbState == newState)
                                {
                                    break;
                                }

                                if (dbState == ExState.Stopped)
                                {
                                    // Do not overwrite STOPPED state
                                    // (but do overwrite newState with the value from the database so that the correct
                                    // current state is reported back to the client)
                                    newState = dbState;
                                    break;
                                }
                                // Presumably the state went from PAUSED to RUNNING or vice versa, try again
                                conflict.Resolve(RefreshMode.KeepCurrentValues);
                            }
                        }
                    }

                    if (i == DB_RETRIES)
                    {
                        log.Info($"Too many retries to set state of execution {executionId} to {newState}");
                        // return the current (and original) state
                        var originalState = ExState.Create(db.ExecutionStates.GetOriginalEntityState(executionState).State);
                        return(((Response)originalState.Json).WithContentType("application/json"));
                    }
                    return(((Response)newState.Json).WithContentType("application/json"));
                }
            };
        }
    }
Beispiel #7
0
        /// <summary>
        /// Process task completion by scheduling the next task or completing the workflow
        /// </summary>
        /// <param name="db"></param>
        /// <param name="workflow"></param>
        /// <param name="execution"></param>
        /// <param name="history"></param>
        /// <param name="decisions"></param>
        private static void ProcessActivityTaskCompletedEvent(Database db, WorkflowObj workflow, Execution execution, History history, List <History> decisions)
        {
            // There should(!) be no contention for the data modified in this process
            var evt           = ActivityTaskCompletedEvent.Create(history);
            var se            = ActivityTaskScheduledEvent.Create(db.GetHistoryEvent(execution.ExecutionId, evt.SchedulingEventId));
            var completedTask = workflow.Tasks.Single(t => t.TaskId == se.TaskId);

            // Default task outflow
            var outflow = "Out";

            // Update variables
            if (evt.Result != null)
            {
                // Update the variables if there are any normal results (not prefixed with "$")
                if (evt.Result.Properties().Any(p => !p.Name.StartsWith("$")))
                {
                    var variables = db.Variables.Where(v => v.Execution == execution).ToArray();
                    foreach (var o in completedTask.Outputs.Where(o => o.Value.Var != null))
                    {
                        // If the activity has not returned a value for an output then we don't update the mapped variable
                        // In general it is probably best if activities return values for all outputs to avoid confusion
                        JToken value;
                        if (evt.Result.TryGetValue(o.Key, out value))
                        {
                            variables.Single(v => v.Name == o.Value.Var).Json = value.ToString(Formatting.None);
                        }
                    }
                }
                // Get the correct outflow
                JToken outflowToken;
                if (evt.Result.TryGetValue("$outflow", out outflowToken))
                {
                    if (outflowToken.Type == JTokenType.String)
                    {
                        outflow = (string)outflowToken;
                    }
                    else
                    {
                        throw new ApplicationException("Task outflow identifier must be a string");
                    }
                }
            }

            var nextTaskId = completedTask.Outflows.Single(o => o.Name == outflow).Target;
            var nextTask   = workflow.Tasks.Single(t => t.TaskId == nextTaskId);

            // A task with no outflows is an end
            if (nextTask.Outflows.Length == 0)
            {
                Console.WriteLine($"Execution state = {execution.ExecutionState.State}");
                if (ExState.Create(execution.ExecutionState.State) != ExState.Cleanup)
                {
                    CreateWorkflowCompletedEvent(execution, decisions);
                }
                AttemptCleanup(db, execution, workflow, decisions);
            }
            else
            {
                CreateTaskScheduledEvent(db, execution, nextTask, decisions);
            }
        }