comparison Framework/Oracle/WebAssemblyOracle.cpp @ 977:262a0244e9b2 toa2019090201

Added missing Unregister for objects that register by the broker + logs + guard in FetchContext
author Benjamin Golinvaux <bgo@osimis.io>
date Mon, 02 Sep 2019 17:29:26 +0200
parents e75fd08d6c75
children a9f5d0742e22
comparison
equal deleted inserted replaced
976:3abc47e051c8 977:262a0244e9b2
87 } 87 }
88 88
89 virtual void EmitMessage(const IObserver& receiver, 89 virtual void EmitMessage(const IObserver& receiver,
90 const IMessage& message) 90 const IMessage& message)
91 { 91 {
92 LOG(TRACE) << "WebAssemblyOracle::Emitter::EmitMessage receiver = "
93 << std::hex << &receiver << std::dec;
92 oracle_.EmitMessage(receiver, message); 94 oracle_.EmitMessage(receiver, message);
93 } 95 }
94 }; 96 };
95 97
96 98 /**
99 This object is created on the heap for every http request.
100 It is deleted in the success (or error) callbacks.
101
102 This object references the receiver of the request. Since this is a raw
103 reference, we need additional checks to make sure we send the response to
104 the same object, for the object can be deleted and a new one recreated at the
105 same address (it often happens in the [single-threaded] browser context).
106 */
97 class WebAssemblyOracle::FetchContext : public boost::noncopyable 107 class WebAssemblyOracle::FetchContext : public boost::noncopyable
98 { 108 {
99 private: 109 private:
100 Emitter emitter_; 110 Emitter emitter_;
101 const IObserver& receiver_; 111 const IObserver& receiver_;
102 std::auto_ptr<IOracleCommand> command_; 112 std::auto_ptr<IOracleCommand> command_;
103 std::string expectedContentType_; 113 std::string expectedContentType_;
114 std::string receiverFingerprint_;
104 115
105 public: 116 public:
106 FetchContext(WebAssemblyOracle& oracle, 117 FetchContext(WebAssemblyOracle& oracle,
107 const IObserver& receiver, 118 const IObserver& receiver,
108 IOracleCommand* command, 119 IOracleCommand* command,
109 const std::string& expectedContentType) : 120 const std::string& expectedContentType) :
110 emitter_(oracle), 121 emitter_(oracle),
111 receiver_(receiver), 122 receiver_(receiver),
112 command_(command), 123 command_(command),
113 expectedContentType_(expectedContentType) 124 expectedContentType_(expectedContentType),
114 { 125 receiverFingerprint_(receiver.GetFingerprint())
126 {
127 LOG(TRACE) << "WebAssemblyOracle::FetchContext::FetchContext() | "
128 << "receiver address = " << std::hex << &receiver << std::dec
129 << " with fingerprint = " << receiverFingerprint_;
130
115 if (command == NULL) 131 if (command == NULL)
116 { 132 {
117 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); 133 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
118 } 134 }
119 } 135 }
123 return expectedContentType_; 139 return expectedContentType_;
124 } 140 }
125 141
126 void EmitMessage(const IMessage& message) 142 void EmitMessage(const IMessage& message)
127 { 143 {
144 LOG(TRACE) << "WebAssemblyOracle::FetchContext::EmitMessage receiver_ = "
145 << std::hex << &receiver_ << std::dec;
128 emitter_.EmitMessage(receiver_, message); 146 emitter_.EmitMessage(receiver_, message);
129 } 147 }
130 148
131 IMessageEmitter& GetEmitter() 149 IMessageEmitter& GetEmitter()
132 { 150 {
196 214
197 std::auto_ptr<FetchContext> context(reinterpret_cast<FetchContext*>(fetch->userData)); 215 std::auto_ptr<FetchContext> context(reinterpret_cast<FetchContext*>(fetch->userData));
198 216
199 // an UUID is 36 chars : 32 hex chars + 4 hyphens: char #0 --> char #35 217 // an UUID is 36 chars : 32 hex chars + 4 hyphens: char #0 --> char #35
200 // char #36 is \0. 218 // char #36 is \0.
219 bool callHandler = true;
201 220
202 // TODO: remove this line because we are NOT allowed to call methods on GetReceiver that is maybe a dangling ref 221 // TODO: remove this line because we are NOT allowed to call methods on GetReceiver that is maybe a dangling ref
203 if (context->GetReceiver().DoesFingerprintLookGood()) { 222 if (context->GetReceiver().DoesFingerprintLookGood())
204 LOG(TRACE) << "SuccessCallback for object at address (" << std::hex << &(context->GetReceiver()) << std::dec << " with current fingerprint = " << context->GetReceiver().GetFingerprint(); 223 {
224 callHandler = true;
225 std::string currentFingerprint(context->GetReceiver().GetFingerprint());
226
227 LOG(TRACE) << "SuccessCallback for object at address (" << std::hex
228 << &(context->GetReceiver()) << std::dec
229 << " with current fingerprint = " << currentFingerprint
230 << ". Fingerprint looks OK";
231
232 if (currentFingerprint != context->receiverFingerprint_)
233 {
234 LOG(TRACE) << " ** SuccessCallback: BUT currentFingerprint != "
235 << "receiverFingerprint_(" << context->receiverFingerprint_ << ")";
236 callHandler = false;
237 }
238 else
239 {
240 LOG(TRACE) << " ** SuccessCallback: FetchContext-level "
241 << "fingerprints are the same: "
242 << context->receiverFingerprint_
243 << " ---> oracle will dispatch the response to observer: "
244 << std::hex << &(context->GetReceiver()) << std::dec;
245 }
205 } 246 }
206 else { 247 else {
207 LOG(TRACE) << "SuccessCallback for object at address (" << std::hex << &(context->GetReceiver()) << std::dec << " with current fingerprint is XXXXX -- NOT A VALID FINGERPRINT! OBJECT IS READ ! CALLBACK WILL NOT BE CALLED!"; 248 LOG(TRACE) << "SuccessCallback for object at address (" << std::hex << &(context->GetReceiver()) << std::dec << " with current fingerprint is XXXXX -- NOT A VALID FINGERPRINT! OBJECT IS READ ! CALLBACK WILL NOT BE CALLED!";
208 } 249 callHandler = false;
209 250 }
210 251
211 if (fetch->userData == NULL) 252 if (fetch->userData == NULL)
212 { 253 {
213 LOG(ERROR) << "WebAssemblyOracle::FetchContext::SuccessCallback fetch->userData is NULL!!!!!!!"; 254 LOG(ERROR) << "WebAssemblyOracle::FetchContext::SuccessCallback fetch->userData is NULL!!!!!!!";
214 } 255 }
259 LOG(ERROR) << "WebAssemblyOracle::FetchContext::SuccessCallback: (context.get() == NULL)"; 300 LOG(ERROR) << "WebAssemblyOracle::FetchContext::SuccessCallback: (context.get() == NULL)";
260 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); 301 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
261 } 302 }
262 else 303 else
263 { 304 {
264 if (context->GetReceiver().DoesFingerprintLookGood()) { 305 if (callHandler)
306 {
265 switch (context->GetCommand().GetType()) 307 switch (context->GetCommand().GetType())
266 { 308 {
267 case IOracleCommand::Type_OrthancRestApi: 309 case IOracleCommand::Type_OrthancRestApi:
268 { 310 {
311 LOG(TRACE) << "WebAssemblyOracle::FetchContext::SuccessCallback. About to call context->EmitMessage(message);";
269 OrthancRestApiCommand::SuccessMessage message 312 OrthancRestApiCommand::SuccessMessage message
270 (context->GetTypedCommand<OrthancRestApiCommand>(), headers, answer); 313 (context->GetTypedCommand<OrthancRestApiCommand>(), headers, answer);
271 context->EmitMessage(message); 314 context->EmitMessage(message);
272 break; 315 break;
273 } 316 }
609 652
610 653
611 void WebAssemblyOracle::Schedule(const IObserver& receiver, 654 void WebAssemblyOracle::Schedule(const IObserver& receiver,
612 IOracleCommand* command) 655 IOracleCommand* command)
613 { 656 {
614 #if 0 657 LOG(TRACE) << "WebAssemblyOracle::Schedule : receiver = "
615 if (logbgo233) { 658 << std::hex << &receiver << std::dec
616 if (logbgo115) 659 << " | Current fingerprint is " << receiver.GetFingerprint();
617 LOG(TRACE) << " WebAssemblyOracle::Schedule command addr " << 660
618 std::hex << command << std::dec;
619 }
620 #endif
621 std::auto_ptr<IOracleCommand> protection(command); 661 std::auto_ptr<IOracleCommand> protection(command);
622 662
623 if (command == NULL) 663 if (command == NULL)
624 { 664 {
625 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); 665 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);