Mercurial > hg > orthanc-stone
annotate Framework/Loaders/LoaderStateMachine.cpp @ 1115:f00deb2b4733
Added tag toa2019110401 for changeset 33b0a762e98a
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Mon, 04 Nov 2019 15:11:44 +0100 |
parents | eb28dfe432f7 |
children | 3e8f59cefec6 2d8ab34c8c91 |
rev | line source |
---|---|
815 | 1 /** |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2019 Osimis S.A., Belgium | |
6 * | |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Affero General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 | |
22 #include "LoaderStateMachine.h" | |
23 | |
24 #include <Core/OrthancException.h> | |
25 | |
26 namespace OrthancStone | |
27 { | |
28 void LoaderStateMachine::State::Handle(const OrthancRestApiCommand::SuccessMessage& message) | |
29 { | |
30 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | |
31 } | |
32 | |
33 | |
34 void LoaderStateMachine::State::Handle(const GetOrthancImageCommand::SuccessMessage& message) | |
35 { | |
36 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | |
37 } | |
38 | |
39 | |
40 void LoaderStateMachine::State::Handle(const GetOrthancWebViewerJpegCommand::SuccessMessage& message) | |
41 { | |
42 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | |
43 } | |
44 | |
45 | |
46 void LoaderStateMachine::Schedule(OracleCommandWithPayload* command) | |
47 { | |
973
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
48 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::Schedule()"; |
964
91f827272c1f
Added cache-control headers for POST requests + #ifdef'd tracing logs + trace on context restored
Benjamin Golinvaux <bgo@osimis.io>
parents:
956
diff
changeset
|
49 |
815 | 50 std::auto_ptr<OracleCommandWithPayload> protection(command); |
51 | |
52 if (command == NULL) | |
53 { | |
54 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
55 } | |
56 | |
57 if (!command->HasPayload()) | |
58 { | |
59 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange, | |
60 "The payload must contain the next state"); | |
61 } | |
62 pendingCommands_.push_back(protection.release()); | |
964
91f827272c1f
Added cache-control headers for POST requests + #ifdef'd tracing logs + trace on context restored
Benjamin Golinvaux <bgo@osimis.io>
parents:
956
diff
changeset
|
63 |
815 | 64 Step(); |
65 } | |
66 | |
67 | |
68 void LoaderStateMachine::Start() | |
69 { | |
973
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
70 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::Start()"; |
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
71 |
815 | 72 if (active_) |
73 { | |
964
91f827272c1f
Added cache-control headers for POST requests + #ifdef'd tracing logs + trace on context restored
Benjamin Golinvaux <bgo@osimis.io>
parents:
956
diff
changeset
|
74 LOG(TRACE) << "LoaderStateMachine::Start() called while active_ is true"; |
815 | 75 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
76 } | |
77 | |
78 active_ = true; | |
79 | |
80 for (size_t i = 0; i < simultaneousDownloads_; i++) | |
81 { | |
82 Step(); | |
83 } | |
84 } | |
85 | |
86 | |
87 void LoaderStateMachine::Step() | |
88 { | |
89 if (!pendingCommands_.empty() && | |
90 activeCommands_ < simultaneousDownloads_) | |
91 { | |
964
91f827272c1f
Added cache-control headers for POST requests + #ifdef'd tracing logs + trace on context restored
Benjamin Golinvaux <bgo@osimis.io>
parents:
956
diff
changeset
|
92 |
91f827272c1f
Added cache-control headers for POST requests + #ifdef'd tracing logs + trace on context restored
Benjamin Golinvaux <bgo@osimis.io>
parents:
956
diff
changeset
|
93 IOracleCommand* nextCommand = pendingCommands_.front(); |
91f827272c1f
Added cache-control headers for POST requests + #ifdef'd tracing logs + trace on context restored
Benjamin Golinvaux <bgo@osimis.io>
parents:
956
diff
changeset
|
94 |
973
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
95 LOG(TRACE) << " LoaderStateMachine(" << std::hex << this << std::dec << |
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
96 ")::Step(): activeCommands_ (" << activeCommands_ << |
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
97 ") < simultaneousDownloads_ (" << simultaneousDownloads_ << |
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
98 ") --> will Schedule command addr " << std::hex << nextCommand << std::dec; |
964
91f827272c1f
Added cache-control headers for POST requests + #ifdef'd tracing logs + trace on context restored
Benjamin Golinvaux <bgo@osimis.io>
parents:
956
diff
changeset
|
99 |
91f827272c1f
Added cache-control headers for POST requests + #ifdef'd tracing logs + trace on context restored
Benjamin Golinvaux <bgo@osimis.io>
parents:
956
diff
changeset
|
100 oracle_.Schedule(*this, nextCommand); |
815 | 101 pendingCommands_.pop_front(); |
102 | |
103 activeCommands_++; | |
104 } | |
964
91f827272c1f
Added cache-control headers for POST requests + #ifdef'd tracing logs + trace on context restored
Benjamin Golinvaux <bgo@osimis.io>
parents:
956
diff
changeset
|
105 else |
91f827272c1f
Added cache-control headers for POST requests + #ifdef'd tracing logs + trace on context restored
Benjamin Golinvaux <bgo@osimis.io>
parents:
956
diff
changeset
|
106 { |
973
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
107 LOG(TRACE) << " LoaderStateMachine(" << std::hex << this << std::dec << |
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
108 ")::Step(): activeCommands_ (" << activeCommands_ << |
1061
eb28dfe432f7
fixed typo in assert. msg. + getters for custom windowing in grayscale layer configurator.
Benjamin Golinvaux <bgo@osimis.io>
parents:
977
diff
changeset
|
109 ") >= simultaneousDownloads_ (" << simultaneousDownloads_ << |
973
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
110 ") --> will NOT Schedule command"; |
964
91f827272c1f
Added cache-control headers for POST requests + #ifdef'd tracing logs + trace on context restored
Benjamin Golinvaux <bgo@osimis.io>
parents:
956
diff
changeset
|
111 } |
815 | 112 } |
113 | |
114 | |
115 void LoaderStateMachine::Clear() | |
116 { | |
973
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
117 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::Clear()"; |
815 | 118 for (PendingCommands::iterator it = pendingCommands_.begin(); |
119 it != pendingCommands_.end(); ++it) | |
120 { | |
121 delete *it; | |
122 } | |
123 | |
124 pendingCommands_.clear(); | |
125 } | |
126 | |
127 | |
128 void LoaderStateMachine::HandleExceptionMessage(const OracleCommandExceptionMessage& message) | |
129 { | |
956
a7351ad54960
Made IsContextLost automatically set the flag by checking with the emscripten
Benjamin Golinvaux <bgo@osimis.io>
parents:
840
diff
changeset
|
130 LOG(ERROR) << "LoaderStateMachine::HandleExceptionMessage: error in the state machine, stopping all processing"; |
840
47fc7919977d
Added details on errors in LoaderStateMachine + dummy change in loader.cpp
Benjamin Golinvaux <bgo@osimis.io>
parents:
815
diff
changeset
|
131 LOG(ERROR) << "Error: " << message.GetException().What() << " Details: " << |
47fc7919977d
Added details on errors in LoaderStateMachine + dummy change in loader.cpp
Benjamin Golinvaux <bgo@osimis.io>
parents:
815
diff
changeset
|
132 message.GetException().GetDetails(); |
47fc7919977d
Added details on errors in LoaderStateMachine + dummy change in loader.cpp
Benjamin Golinvaux <bgo@osimis.io>
parents:
815
diff
changeset
|
133 Clear(); |
815 | 134 } |
135 | |
136 template <typename T> | |
137 void LoaderStateMachine::HandleSuccessMessage(const T& message) | |
138 { | |
977
262a0244e9b2
Added missing Unregister for objects that register by the broker + logs + guard in FetchContext
Benjamin Golinvaux <bgo@osimis.io>
parents:
975
diff
changeset
|
139 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::HandleSuccessMessage(). Receiver fingerprint = " << GetFingerprint(); |
973
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
140 if (activeCommands_ <= 0) { |
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
141 LOG(ERROR) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::HandleSuccessMessage : activeCommands_ should be > 0 but is: " << activeCommands_; |
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
142 } |
975
e75fd08d6c75
Cleaning in ICallable + changed fingerprint to plain char array to allow for
Benjamin Golinvaux <bgo@osimis.io>
parents:
973
diff
changeset
|
143 else { |
e75fd08d6c75
Cleaning in ICallable + changed fingerprint to plain char array to allow for
Benjamin Golinvaux <bgo@osimis.io>
parents:
973
diff
changeset
|
144 activeCommands_--; |
e75fd08d6c75
Cleaning in ICallable + changed fingerprint to plain char array to allow for
Benjamin Golinvaux <bgo@osimis.io>
parents:
973
diff
changeset
|
145 try |
e75fd08d6c75
Cleaning in ICallable + changed fingerprint to plain char array to allow for
Benjamin Golinvaux <bgo@osimis.io>
parents:
973
diff
changeset
|
146 { |
e75fd08d6c75
Cleaning in ICallable + changed fingerprint to plain char array to allow for
Benjamin Golinvaux <bgo@osimis.io>
parents:
973
diff
changeset
|
147 dynamic_cast<State&>(message.GetOrigin().GetPayload()).Handle(message); |
e75fd08d6c75
Cleaning in ICallable + changed fingerprint to plain char array to allow for
Benjamin Golinvaux <bgo@osimis.io>
parents:
973
diff
changeset
|
148 Step(); |
e75fd08d6c75
Cleaning in ICallable + changed fingerprint to plain char array to allow for
Benjamin Golinvaux <bgo@osimis.io>
parents:
973
diff
changeset
|
149 } |
e75fd08d6c75
Cleaning in ICallable + changed fingerprint to plain char array to allow for
Benjamin Golinvaux <bgo@osimis.io>
parents:
973
diff
changeset
|
150 catch (Orthanc::OrthancException& e) |
e75fd08d6c75
Cleaning in ICallable + changed fingerprint to plain char array to allow for
Benjamin Golinvaux <bgo@osimis.io>
parents:
973
diff
changeset
|
151 { |
e75fd08d6c75
Cleaning in ICallable + changed fingerprint to plain char array to allow for
Benjamin Golinvaux <bgo@osimis.io>
parents:
973
diff
changeset
|
152 LOG(ERROR) << "Error in the state machine, stopping all processing: " << |
e75fd08d6c75
Cleaning in ICallable + changed fingerprint to plain char array to allow for
Benjamin Golinvaux <bgo@osimis.io>
parents:
973
diff
changeset
|
153 e.What() << " Details: " << e.GetDetails(); |
e75fd08d6c75
Cleaning in ICallable + changed fingerprint to plain char array to allow for
Benjamin Golinvaux <bgo@osimis.io>
parents:
973
diff
changeset
|
154 Clear(); |
e75fd08d6c75
Cleaning in ICallable + changed fingerprint to plain char array to allow for
Benjamin Golinvaux <bgo@osimis.io>
parents:
973
diff
changeset
|
155 } |
815 | 156 } |
157 } | |
158 | |
159 | |
160 LoaderStateMachine::LoaderStateMachine(IOracle& oracle, | |
161 IObservable& oracleObservable) : | |
162 IObserver(oracleObservable.GetBroker()), | |
163 oracle_(oracle), | |
977
262a0244e9b2
Added missing Unregister for objects that register by the broker + logs + guard in FetchContext
Benjamin Golinvaux <bgo@osimis.io>
parents:
975
diff
changeset
|
164 oracleObservable_(oracleObservable), |
815 | 165 active_(false), |
166 simultaneousDownloads_(4), | |
167 activeCommands_(0) | |
168 { | |
973
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
169 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::LoaderStateMachine()"; |
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
170 |
815 | 171 oracleObservable.RegisterObserverCallback( |
172 new Callable<LoaderStateMachine, OrthancRestApiCommand::SuccessMessage> | |
173 (*this, &LoaderStateMachine::HandleSuccessMessage)); | |
174 | |
175 oracleObservable.RegisterObserverCallback( | |
176 new Callable<LoaderStateMachine, GetOrthancImageCommand::SuccessMessage> | |
177 (*this, &LoaderStateMachine::HandleSuccessMessage)); | |
178 | |
179 oracleObservable.RegisterObserverCallback( | |
180 new Callable<LoaderStateMachine, GetOrthancWebViewerJpegCommand::SuccessMessage> | |
181 (*this, &LoaderStateMachine::HandleSuccessMessage)); | |
182 | |
183 oracleObservable.RegisterObserverCallback( | |
184 new Callable<LoaderStateMachine, OracleCommandExceptionMessage> | |
185 (*this, &LoaderStateMachine::HandleExceptionMessage)); | |
186 } | |
187 | |
973
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
188 LoaderStateMachine::~LoaderStateMachine() |
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
189 { |
977
262a0244e9b2
Added missing Unregister for objects that register by the broker + logs + guard in FetchContext
Benjamin Golinvaux <bgo@osimis.io>
parents:
975
diff
changeset
|
190 oracleObservable_.Unregister(this); |
973
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
191 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::~LoaderStateMachine()"; |
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
192 Clear(); |
38409549db43
Log with addresses + added fingerprint mechanism to avoid calling zombie objects
Benjamin Golinvaux <bgo@osimis.io>
parents:
964
diff
changeset
|
193 } |
815 | 194 |
195 void LoaderStateMachine::SetSimultaneousDownloads(unsigned int count) | |
196 { | |
197 if (active_) | |
198 { | |
956
a7351ad54960
Made IsContextLost automatically set the flag by checking with the emscripten
Benjamin Golinvaux <bgo@osimis.io>
parents:
840
diff
changeset
|
199 LOG(ERROR) << "LoaderStateMachine::SetSimultaneousDownloads called while active_ is true"; |
815 | 200 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
201 } | |
202 else if (count == 0) | |
203 { | |
204 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
205 } | |
206 else | |
207 { | |
208 simultaneousDownloads_ = count; | |
209 } | |
210 } | |
211 } |