comparison Framework/Deprecated/Loaders/LoaderStateMachine.cpp @ 1225:16738485e457 broker

deprecating DicomStructureSetLoader, OrthancMultiframeVolumeLoader and OrthancSeriesVolumeProgressiveLoader
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sun, 08 Dec 2019 11:45:09 +0100
parents Framework/Loaders/LoaderStateMachine.cpp@a0a33e5ea5bb
children 0ca50d275b9a
comparison
equal deleted inserted replaced
1224:37bc7f115f81 1225:16738485e457
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 Deprecated
27 {
28 void LoaderStateMachine::State::Handle(const OrthancStone::OrthancRestApiCommand::SuccessMessage& message)
29 {
30 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
31 }
32
33
34 void LoaderStateMachine::State::Handle(const OrthancStone::GetOrthancImageCommand::SuccessMessage& message)
35 {
36 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
37 }
38
39
40 void LoaderStateMachine::State::Handle(const OrthancStone::GetOrthancWebViewerJpegCommand::SuccessMessage& message)
41 {
42 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
43 }
44
45
46 void LoaderStateMachine::Schedule(OrthancStone::OracleCommandBase* command)
47 {
48 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::Schedule()";
49
50 std::auto_ptr<OrthancStone::OracleCommandBase> 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());
63
64 Step();
65 }
66
67
68 void LoaderStateMachine::Start()
69 {
70 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::Start()";
71
72 if (active_)
73 {
74 LOG(TRACE) << "LoaderStateMachine::Start() called while active_ is true";
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 {
92
93 OrthancStone::IOracleCommand* nextCommand = pendingCommands_.front();
94
95 LOG(TRACE) << " LoaderStateMachine(" << std::hex << this << std::dec <<
96 ")::Step(): activeCommands_ (" << activeCommands_ <<
97 ") < simultaneousDownloads_ (" << simultaneousDownloads_ <<
98 ") --> will Schedule command addr " << std::hex << nextCommand << std::dec;
99
100 boost::shared_ptr<IObserver> observer(GetSharedObserver());
101 oracle_.Schedule(observer, nextCommand);
102 pendingCommands_.pop_front();
103
104 activeCommands_++;
105 }
106 else
107 {
108 LOG(TRACE) << " LoaderStateMachine(" << std::hex << this << std::dec <<
109 ")::Step(): activeCommands_ (" << activeCommands_ <<
110 ") >= simultaneousDownloads_ (" << simultaneousDownloads_ <<
111 ") --> will NOT Schedule command";
112 }
113 }
114
115
116 void LoaderStateMachine::Clear()
117 {
118 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::Clear()";
119 for (PendingCommands::iterator it = pendingCommands_.begin();
120 it != pendingCommands_.end(); ++it)
121 {
122 delete *it;
123 }
124
125 pendingCommands_.clear();
126 }
127
128
129 void LoaderStateMachine::HandleExceptionMessage(const OrthancStone::OracleCommandExceptionMessage& message)
130 {
131 LOG(ERROR) << "LoaderStateMachine::HandleExceptionMessage: error in the state machine, stopping all processing";
132 LOG(ERROR) << "Error: " << message.GetException().What() << " Details: " <<
133 message.GetException().GetDetails();
134 Clear();
135 }
136
137 template <typename T>
138 void LoaderStateMachine::HandleSuccessMessage(const T& message)
139 {
140 if (activeCommands_ <= 0) {
141 LOG(ERROR) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::HandleSuccessMessage : activeCommands_ should be > 0 but is: " << activeCommands_;
142 }
143 else {
144 activeCommands_--;
145 try
146 {
147 dynamic_cast<State&>(message.GetOrigin().GetPayload()).Handle(message);
148 Step();
149 }
150 catch (Orthanc::OrthancException& e)
151 {
152 LOG(ERROR) << "Error in the state machine, stopping all processing: " <<
153 e.What() << " Details: " << e.GetDetails();
154 Clear();
155 }
156 }
157 }
158
159
160 LoaderStateMachine::LoaderStateMachine(OrthancStone::IOracle& oracle,
161 OrthancStone::IObservable& oracleObservable) :
162 oracle_(oracle),
163 active_(false),
164 simultaneousDownloads_(4),
165 activeCommands_(0)
166 {
167 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::LoaderStateMachine()";
168
169 // TODO => Move this out of constructor
170 Register<OrthancStone::OrthancRestApiCommand::SuccessMessage>(oracleObservable, &LoaderStateMachine::HandleSuccessMessage);
171 Register<OrthancStone::GetOrthancImageCommand::SuccessMessage>(oracleObservable, &LoaderStateMachine::HandleSuccessMessage);
172 Register<OrthancStone::GetOrthancWebViewerJpegCommand::SuccessMessage>(oracleObservable, &LoaderStateMachine::HandleSuccessMessage);
173 Register<OrthancStone::OracleCommandExceptionMessage>(oracleObservable, &LoaderStateMachine::HandleExceptionMessage);
174 }
175
176 LoaderStateMachine::~LoaderStateMachine()
177 {
178 LOG(TRACE) << "LoaderStateMachine(" << std::hex << this << std::dec << ")::~LoaderStateMachine()";
179 Clear();
180 }
181
182 void LoaderStateMachine::SetSimultaneousDownloads(unsigned int count)
183 {
184 if (active_)
185 {
186 LOG(ERROR) << "LoaderStateMachine::SetSimultaneousDownloads called while active_ is true";
187 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
188 }
189 else if (count == 0)
190 {
191 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
192 }
193 else
194 {
195 simultaneousDownloads_ = count;
196 }
197 }
198 }