comparison Samples/Sdl/Loader.cpp @ 622:8a3a25f2d42c

uncoupling oracle from context
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 07 May 2019 12:32:21 +0200
parents 9cd19b28f011
children 42dadae61fa9
comparison
equal deleted inserted replaced
621:8adc8cfb50c7 622:8a3a25f2d42c
60 60
61 virtual Type GetType() const = 0; 61 virtual Type GetType() const = 0;
62 }; 62 };
63 63
64 64
65 class IMessageEmitter : public boost::noncopyable
66 {
67 public:
68 virtual ~IMessageEmitter()
69 {
70 }
71
72 virtual void EmitMessage(const OrthancStone::IMessage& message) = 0;
73 };
74
75
65 class IOracle : public boost::noncopyable 76 class IOracle : public boost::noncopyable
66 { 77 {
67 public: 78 public:
68 virtual ~IOracle() 79 virtual ~IOracle()
69 { 80 {
266 } 277 }
267 }; 278 };
268 279
269 280
270 281
271 class NativeApplicationContext : public boost::noncopyable
272 {
273 private:
274 boost::shared_mutex mutex_;
275 Orthanc::WebServiceParameters orthanc_;
276 OrthancStone::MessageBroker broker_;
277 OrthancStone::IObservable oracleObservable_;
278
279 public:
280 NativeApplicationContext() :
281 oracleObservable_(broker_)
282 {
283 orthanc_.SetUrl("http://localhost:8042/");
284 }
285
286
287 class ReaderLock : public boost::noncopyable
288 {
289 private:
290 NativeApplicationContext& that_;
291 boost::shared_lock<boost::shared_mutex> lock_;
292
293 public:
294 ReaderLock(NativeApplicationContext& that) :
295 that_(that),
296 lock_(that.mutex_)
297 {
298 }
299
300 const Orthanc::WebServiceParameters& GetOrthancParameters() const
301 {
302 return that_.orthanc_;
303 }
304 };
305
306
307 class WriterLock : public boost::noncopyable
308 {
309 private:
310 NativeApplicationContext& that_;
311 boost::unique_lock<boost::shared_mutex> lock_;
312
313 public:
314 WriterLock(NativeApplicationContext& that) :
315 that_(that),
316 lock_(that.mutex_)
317 {
318 }
319
320 OrthancStone::MessageBroker& GetBroker()
321 {
322 return that_.broker_;
323 }
324
325 void SetOrthancParameters(Orthanc::WebServiceParameters& orthanc)
326 {
327 that_.orthanc_ = orthanc;
328 }
329
330 OrthancStone::IObservable& GetOracleObservable()
331 {
332 return that_.oracleObservable_;
333 }
334 };
335 };
336
337
338
339 class NativeOracle : public IOracle 282 class NativeOracle : public IOracle
340 { 283 {
341 private: 284 private:
342 class Item : public Orthanc::IDynamicObject 285 class Item : public Orthanc::IDynamicObject
343 { 286 {
368 State_Running, 311 State_Running,
369 State_Stopped 312 State_Stopped
370 }; 313 };
371 314
372 315
373 NativeApplicationContext& context_; 316 IMessageEmitter& emitter_;
374 Orthanc::SharedMessageQueue queue_; 317 Orthanc::WebServiceParameters orthanc_;
375 State state_; 318 Orthanc::SharedMessageQueue queue_;
376 boost::mutex mutex_; 319 State state_;
377 std::vector<boost::thread*> workers_; 320 boost::mutex mutex_;
321 std::vector<boost::thread*> workers_;
378 322
379 323
380 void Execute(const OrthancApiOracleCommand& command) 324 void Execute(const OrthancApiOracleCommand& command)
381 { 325 {
382 std::auto_ptr<Orthanc::HttpClient> client; 326 Orthanc::HttpClient client(orthanc_, command.GetUri());
383 327 client.SetMethod(command.GetMethod());
384 { 328 client.SetBody(command.GetBody());
385 NativeApplicationContext::ReaderLock lock(context_); 329 client.SetTimeout(command.GetTimeout());
386 client.reset(new Orthanc::HttpClient(lock.GetOrthancParameters(), command.GetUri()));
387 }
388
389 client->SetMethod(command.GetMethod());
390 client->SetBody(command.GetBody());
391 client->SetTimeout(command.GetTimeout());
392 330
393 { 331 {
394 const HttpHeaders& headers = command.GetHttpHeaders(); 332 const HttpHeaders& headers = command.GetHttpHeaders();
395 for (HttpHeaders::const_iterator it = headers.begin(); it != headers.end(); it++ ) 333 for (HttpHeaders::const_iterator it = headers.begin(); it != headers.end(); it++ )
396 { 334 {
397 client->AddHeader(it->first, it->second); 335 client.AddHeader(it->first, it->second);
398 } 336 }
399 } 337 }
400 338
401 std::string answer; 339 std::string answer;
402 HttpHeaders answerHeaders; 340 HttpHeaders answerHeaders;
403 341
404 bool success; 342 bool success;
405 try 343 try
406 { 344 {
407 success = client->Apply(answer, answerHeaders); 345 success = client.Apply(answer, answerHeaders);
408 } 346 }
409 catch (Orthanc::OrthancException& e) 347 catch (Orthanc::OrthancException& e)
410 { 348 {
411 success = false; 349 success = false;
412 } 350 }
413 351
414 { 352 if (success)
415 NativeApplicationContext::WriterLock lock(context_); 353 {
416 354 OrthancApiOracleCommand::SuccessMessage message(command, answerHeaders, answer);
417 if (success) 355 emitter_.EmitMessage(message);
418 { 356 }
419 OrthancApiOracleCommand::SuccessMessage message(command, answerHeaders, answer); 357 else
420 lock.GetOracleObservable().EmitMessage(message); 358 {
421 } 359 OrthancApiOracleCommand::FailureMessage message(command, client.GetLastStatus());
422 else 360 emitter_.EmitMessage(message);
423 {
424 OrthancApiOracleCommand::FailureMessage message(command, client->GetLastStatus());
425 lock.GetOracleObservable().EmitMessage(message);
426 }
427 } 361 }
428 } 362 }
429 363
430 364
431 365
499 } 433 }
500 } 434 }
501 435
502 436
503 public: 437 public:
504 NativeOracle(NativeApplicationContext& context) : 438 NativeOracle(IMessageEmitter& emitter) :
505 context_(context), 439 emitter_(emitter),
506 state_(State_Setup), 440 state_(State_Setup),
507 workers_(4) 441 workers_(4)
508 { 442 {
509 } 443 }
510 444
511 virtual ~NativeOracle() 445 virtual ~NativeOracle()
512 { 446 {
513 StopInternal(); 447 StopInternal();
514 } 448 }
515 449
450 void SetOrthancParameters(const Orthanc::WebServiceParameters& orthanc)
451 {
452 boost::mutex::scoped_lock lock(mutex_);
453
454 if (state_ != State_Setup)
455 {
456 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
457 }
458 else
459 {
460 orthanc_ = orthanc;
461 }
462 }
463
516 void SetWorkersCount(unsigned int count) 464 void SetWorkersCount(unsigned int count)
517 { 465 {
518 boost::mutex::scoped_lock lock(mutex_); 466 boost::mutex::scoped_lock lock(mutex_);
519 467
520 if (count <= 0) 468 if (count <= 0)
557 505
558 virtual void Schedule(IOracleCommand* command) 506 virtual void Schedule(IOracleCommand* command)
559 { 507 {
560 queue_.Enqueue(new Item(command)); 508 queue_.Enqueue(new Item(command));
561 } 509 }
510 };
511
512
513
514 class NativeApplicationContext : public IMessageEmitter
515 {
516 private:
517 boost::shared_mutex mutex_;
518 OrthancStone::MessageBroker broker_;
519 OrthancStone::IObservable oracleObservable_;
520
521 public:
522 NativeApplicationContext() :
523 oracleObservable_(broker_)
524 {
525 }
526
527
528 virtual void EmitMessage(const OrthancStone::IMessage& message)
529 {
530 boost::unique_lock<boost::shared_mutex> lock(mutex_);
531 oracleObservable_.EmitMessage(message);
532 }
533
534
535 class ReaderLock : public boost::noncopyable
536 {
537 private:
538 NativeApplicationContext& that_;
539 boost::shared_lock<boost::shared_mutex> lock_;
540
541 public:
542 ReaderLock(NativeApplicationContext& that) :
543 that_(that),
544 lock_(that.mutex_)
545 {
546 }
547 };
548
549
550 class WriterLock : public boost::noncopyable
551 {
552 private:
553 NativeApplicationContext& that_;
554 boost::unique_lock<boost::shared_mutex> lock_;
555
556 public:
557 WriterLock(NativeApplicationContext& that) :
558 that_(that),
559 lock_(that.mutex_)
560 {
561 }
562
563 OrthancStone::MessageBroker& GetBroker()
564 {
565 return that_.broker_;
566 }
567
568 OrthancStone::IObservable& GetOracleObservable()
569 {
570 return that_.oracleObservable_;
571 }
572 };
562 }; 573 };
563 } 574 }
564 575
565 576
566 577
598 Refactoring::NativeApplicationContext::WriterLock lock(context); 609 Refactoring::NativeApplicationContext::WriterLock lock(context);
599 toto.reset(new Toto(lock.GetOracleObservable())); 610 toto.reset(new Toto(lock.GetOracleObservable()));
600 } 611 }
601 612
602 Refactoring::NativeOracle oracle(context); 613 Refactoring::NativeOracle oracle(context);
614
615 {
616 Orthanc::WebServiceParameters p;
617 //p.SetUrl("http://localhost:8043/");
618 p.SetCredentials("orthanc", "orthanc");
619 oracle.SetOrthancParameters(p);
620 }
621
603 oracle.Start(); 622 oracle.Start();
604 623
605 { 624 {
606 Json::Value v = Json::objectValue; 625 Json::Value v = Json::objectValue;
607 v["Level"] = "Series"; 626 v["Level"] = "Series";