annotate Implab/Components/RunnableComponent.cs @ 156:97fbbf816844 v2

Promises: SignalXXX methods merged into SignalHandler method. Components: RunnableComponent In progress
author cin
date Mon, 15 Feb 2016 04:22:15 +0300
parents
children 948c015a9011
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
156
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
1 using System;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
2 using Implab.Parsing;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
3
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
4 namespace Implab.Components {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
5 public class RunnableComponent : Disposable, IRunnable, IInitializable {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
6 class Automaton : DFAutomaton<ExecutionState> {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
7 static readonly EDFADefinition<ExecutionState> _dfa;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
8
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
9 static Automaton() {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
10
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
11 var token = Token
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
12 .New(ExecutionState.Uninitialized).Optional() // we can skip uninitialized state
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
13 .Cat(
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
14 Token.New(ExecutionState.Ready) // uninitialized -> initial
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
15 .Cat(
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
16 Token.New(ExecutionState.Starting) // initial -> starting
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
17 .Cat(
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
18 Token.New(ExecutionState.Running) // running -> {stopping -> stopped | failed }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
19 .Cat(
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
20 Token.New(ExecutionState.Stopping) // running -> stopping
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
21 .Cat(
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
22 Token.New(ExecutionState.Stopped) // stopping -> stopped
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
23 .Or(Token.New(ExecutionState.Failed)) // stopping -> failed
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
24 )
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
25 .Or(Token.New(ExecutionState.Failed)) // running -> failed
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
26 )
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
27 .Or(Token.New(ExecutionState.Failed)) // starting -> failed
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
28 ).EClosure()
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
29 )
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
30 .Or(Token.New(ExecutionState.Failed)) // uninitialized->failed
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
31 .Cat(Token.New(ExecutionState.Disposed).Tag(0)) // ... -> disposed
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
32 );
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
33
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
34 var builder = new DFABuilder();
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
35 token.Accept(builder);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
36
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
37 var _dfa = new EDFADefinition<ExecutionState>(EnumAlphabet<ExecutionState>.FullAlphabet);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
38 builder.BuildDFA(_dfa); // don't optimize dfa to avoid remapping of the alphabet
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
39
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
40 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
41
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
42 public Automaton() : base(_dfa.States, INITIAL_STATE, ExecutionState.Reserved) {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
43 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
44
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
45 public void MoveTo(ExecutionState state) {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
46
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
47 if (!CanMove((int)state))
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
48 throw new InvalidOperationException(String.Format("Illegal state transition from {0} to {1}", Current, state));
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
49 Move((int)state);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
50 m_context.info = state;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
51 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
52
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
53 public ExecutionState Current {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
54 get {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
55 return (ExecutionState)m_context.info;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
56 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
57 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
58 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
59
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
60 readonly Automaton m_automaton = new Automaton();
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
61 IPromise m_pending;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
62 Exception m_lastError;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
63
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
64 protected RunnableComponent(bool initialized) {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
65 if (initialized)
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
66 m_automaton.MoveTo(ExecutionState.Ready);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
67 else
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
68 m_automaton.MoveTo(ExecutionState.Uninitialized);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
69 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
70
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
71 #region IInitializable implementation
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
72
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
73 public void Init() {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
74
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
75 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
76
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
77 #endregion
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
78
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
79 #region IRunnable implementation
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
80
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
81 public IPromise Start() {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
82 return Safe.InvokePromise(() => {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
83 Promise promise;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
84 lock (m_automaton) {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
85 if (m_automaton.Current == ExecutionState.Starting)
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
86 return m_pending;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
87 m_automaton.MoveTo(ExecutionState.Starting);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
88 m_pending = promise = new Promise();
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
89 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
90
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
91 var start = Safe.InvokePromise(OnStart);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
92 promise.On(null, null, start.Cancel);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
93 start.On(promise.Resolve, promise.Reject, promise.CancelOperation);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
94
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
95 return promise.Then(() => {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
96 lock(m_automaton) {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
97 m_automaton.MoveTo(ExecutionState.Running);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
98 m_pending = null;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
99 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
100
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
101 Run();
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
102 }, err => {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
103 if (BeginTransition(RUNNING_REQUIRE)) {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
104 m_lastError = err;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
105 CompleteTransition(FAILED_STATE);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
106 throw new PromiseTransientException(err);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
107 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
108 throw new OperationCanceledException();
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
109 }, reason => {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
110 throw new OperationCanceledException("The operation was cancelled", reason);
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
111 });
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
112 });
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
113 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
114
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
115 protected virtual IPromise OnStart() {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
116 return Promise.SUCCESS;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
117 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
118
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
119 protected virtual void Run() {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
120 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
121
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
122 public IPromise Stop() {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
123 throw new NotImplementedException();
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
124 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
125
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
126 public ExecutionState State {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
127 get {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
128 throw new NotImplementedException();
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
129 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
130 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
131
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
132 public Exception LastError {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
133 get {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
134 throw new NotImplementedException();
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
135 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
136 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
137
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
138 #endregion
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
139 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
140 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
141