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