Mercurial > hg > orthanc
comparison UnitTestsSources/MultiThreadingTests.cpp @ 2562:1e66fe3ddf9f jobs
refactoring
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 04 May 2018 17:28:47 +0200 |
parents | 9b7680dee75d |
children | 98dfc1948d00 |
comparison
equal
deleted
inserted
replaced
2560:7d4a3eca96af | 2562:1e66fe3ddf9f |
---|---|
288 JobState_Failure, | 288 JobState_Failure, |
289 JobState_Paused, | 289 JobState_Paused, |
290 JobState_Retry | 290 JobState_Retry |
291 }; | 291 }; |
292 | 292 |
293 enum JobStepStatus | 293 enum JobStepCode |
294 { | 294 { |
295 JobStepStatus_Success, | 295 JobStepCode_Success, |
296 JobStepStatus_Failure, | 296 JobStepCode_Failure, |
297 JobStepStatus_Continue, | 297 JobStepCode_Continue, |
298 JobStepStatus_Retry | 298 JobStepCode_Retry |
299 }; | 299 }; |
300 | 300 |
301 | 301 |
302 class JobStepResult | 302 class JobStepResult |
303 { | 303 { |
304 private: | 304 private: |
305 JobStepStatus status_; | 305 JobStepCode status_; |
306 | 306 |
307 public: | 307 public: |
308 explicit JobStepResult(JobStepStatus status) : | 308 explicit JobStepResult(JobStepCode status) : |
309 status_(status) | 309 status_(status) |
310 { | 310 { |
311 } | 311 } |
312 | 312 |
313 virtual ~JobStepResult() | 313 virtual ~JobStepResult() |
314 { | 314 { |
315 } | 315 } |
316 | 316 |
317 JobStepStatus GetStatus() const | 317 JobStepCode GetCode() const |
318 { | 318 { |
319 return status_; | 319 return status_; |
320 } | 320 } |
321 }; | 321 }; |
322 | 322 |
326 private: | 326 private: |
327 unsigned int timeout_; // Retry after "timeout_" milliseconds | 327 unsigned int timeout_; // Retry after "timeout_" milliseconds |
328 | 328 |
329 public: | 329 public: |
330 RetryResult(unsigned int timeout) : | 330 RetryResult(unsigned int timeout) : |
331 JobStepResult(JobStepStatus_Retry), | 331 JobStepResult(JobStepCode_Retry), |
332 timeout_(timeout) | 332 timeout_(timeout) |
333 { | 333 { |
334 } | 334 } |
335 | 335 |
336 unsigned int GetTimeout() const | 336 unsigned int GetTimeout() const |
352 virtual void ReleaseResources() = 0; // For pausing jobs | 352 virtual void ReleaseResources() = 0; // For pausing jobs |
353 | 353 |
354 virtual float GetProgress() = 0; | 354 virtual float GetProgress() = 0; |
355 | 355 |
356 virtual void FormatStatus(Json::Value& value) = 0; | 356 virtual void FormatStatus(Json::Value& value) = 0; |
357 }; | |
358 | |
359 | |
360 struct JobStatus | |
361 { | |
362 ErrorCode errorCode_; | |
363 float progress_; | |
364 Json::Value description_; | |
365 | |
366 JobStatus() : | |
367 errorCode_(ErrorCode_Success), | |
368 progress_(0), | |
369 description_(Json::objectValue) | |
370 { | |
371 } | |
372 | |
373 JobStatus(ErrorCode code, | |
374 float progress) : | |
375 errorCode_(code), | |
376 progress_(progress), | |
377 description_(Json::objectValue) | |
378 { | |
379 if (progress < 0 || | |
380 progress > 1) | |
381 { | |
382 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
383 } | |
384 } | |
357 }; | 385 }; |
358 | 386 |
359 | 387 |
360 class JobInfo | 388 class JobInfo |
361 { | 389 { |
362 private: | 390 private: |
363 std::string id_; | 391 std::string id_; |
364 int priority_; | 392 int priority_; |
365 ErrorCode errorCode_; | 393 ErrorCode errorCode_; |
366 JobState state_; | 394 JobState state_; |
367 float progress_; | |
368 boost::posix_time::ptime infoTime_; | 395 boost::posix_time::ptime infoTime_; |
369 boost::posix_time::ptime creationTime_; | 396 boost::posix_time::ptime creationTime_; |
370 boost::posix_time::time_duration runtime_; | 397 boost::posix_time::time_duration runtime_; |
371 boost::posix_time::ptime eta_; | 398 boost::posix_time::ptime eta_; |
372 Json::Value status_; | 399 JobStatus status_; |
373 | 400 |
374 public: | 401 public: |
375 JobInfo(const std::string& id, | 402 JobInfo(const std::string& id, |
376 int priority, | 403 int priority, |
377 ErrorCode errorCode, | |
378 JobState state, | 404 JobState state, |
379 float progress, | 405 const JobStatus& status, |
380 const boost::posix_time::ptime& creationTime, | 406 const boost::posix_time::ptime& creationTime, |
381 const boost::posix_time::time_duration& runtime) : | 407 const boost::posix_time::time_duration& runtime) : |
382 id_(id), | 408 id_(id), |
383 priority_(priority), | 409 priority_(priority), |
384 errorCode_(errorCode), | |
385 state_(state), | 410 state_(state), |
386 progress_(progress), | |
387 infoTime_(boost::posix_time::microsec_clock::universal_time()), | 411 infoTime_(boost::posix_time::microsec_clock::universal_time()), |
388 creationTime_(creationTime), | 412 creationTime_(creationTime), |
389 runtime_(runtime) | 413 runtime_(runtime), |
390 { | 414 status_(status) |
391 if (progress < 0 || | 415 { |
392 progress > 1) | 416 float ms = static_cast<float>(runtime_.total_milliseconds()); |
393 { | 417 float remaining = boost::math::llround(1.0f - status_.progress_) * ms; |
394 throw OrthancException(ErrorCode_ParameterOutOfRange); | 418 eta_ = infoTime_ + boost::posix_time::milliseconds(remaining); |
395 } | |
396 | |
397 float r = static_cast<float>(runtime_.total_milliseconds()); | |
398 | |
399 eta_ = infoTime_ + boost::posix_time::milliseconds(boost::math::llround(1.0f - progress) * r); | |
400 } | 419 } |
401 | 420 |
402 const std::string& GetIdentifier() const | 421 const std::string& GetIdentifier() const |
403 { | 422 { |
404 return id_; | 423 return id_; |
417 JobState GetState() const | 436 JobState GetState() const |
418 { | 437 { |
419 return state_; | 438 return state_; |
420 } | 439 } |
421 | 440 |
422 float GetProgress() const | |
423 { | |
424 return progress_; | |
425 } | |
426 | |
427 const boost::posix_time::ptime& GetInfoTime() const | 441 const boost::posix_time::ptime& GetInfoTime() const |
428 { | 442 { |
429 return infoTime_; | 443 return infoTime_; |
430 } | 444 } |
431 | 445 |
442 const boost::posix_time::ptime& GetEstimatedTimeOfArrival() const | 456 const boost::posix_time::ptime& GetEstimatedTimeOfArrival() const |
443 { | 457 { |
444 return eta_; | 458 return eta_; |
445 } | 459 } |
446 | 460 |
447 const Json::Value& GetStatus() const | 461 const JobStatus& GetStatus() const |
448 { | 462 { |
449 return status_; | 463 return status_; |
450 } | 464 } |
451 | 465 |
452 Json::Value& GetStatus() | 466 JobStatus& GetStatus() |
453 { | 467 { |
454 return status_; | 468 return status_; |
455 } | 469 } |
456 }; | 470 }; |
457 | 471 |
458 | 472 |
459 class JobHandler : public boost::noncopyable | 473 class JobHandler : public boost::noncopyable |
460 { | 474 { |
461 private: | 475 private: |
462 std::string id_; | 476 std::string id_; |
463 JobState state_; | 477 JobState state_; |
464 boost::mutex jobMutex_; | |
465 std::auto_ptr<IJob> job_; | 478 std::auto_ptr<IJob> job_; |
466 int priority_; // "+inf()" means highest priority | 479 int priority_; // "+inf()" means highest priority |
467 boost::posix_time::ptime creationTime_; | 480 boost::posix_time::ptime creationTime_; |
468 boost::posix_time::ptime lastStateChangeTime; | 481 boost::posix_time::ptime lastStateChangeTime_; |
482 boost::posix_time::time_duration runtime_; | |
469 boost::posix_time::ptime retryTime_; | 483 boost::posix_time::ptime retryTime_; |
470 boost::posix_time::time_duration runtime_; | |
471 bool pauseScheduled_; | 484 bool pauseScheduled_; |
472 ErrorCode lastErrorCode_; | 485 JobStatus lastStatus_; |
473 float lastProgress_; | |
474 Json::Value lastStatus_; | |
475 | 486 |
476 void SetStateInternal(JobState state) | 487 void SetStateInternal(JobState state) |
477 { | 488 { |
478 const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); | 489 const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); |
479 | 490 |
480 if (state_ == JobState_Running) | 491 if (state_ == JobState_Running) |
481 { | 492 { |
482 runtime_ += (now - lastStateChangeTime); | 493 runtime_ += (now - lastStateChangeTime_); |
483 } | 494 } |
484 | 495 |
485 state_ = state; | 496 state_ = state; |
486 lastStateChangeTime = now; | 497 lastStateChangeTime_ = now; |
487 pauseScheduled_ = false; | 498 pauseScheduled_ = false; |
488 } | 499 } |
489 | 500 |
490 public: | 501 public: |
491 JobHandler(IJob* job, | 502 JobHandler(IJob* job, |
493 id_(Toolbox::GenerateUuid()), | 504 id_(Toolbox::GenerateUuid()), |
494 state_(JobState_Pending), | 505 state_(JobState_Pending), |
495 job_(job), | 506 job_(job), |
496 priority_(priority), | 507 priority_(priority), |
497 creationTime_(boost::posix_time::microsec_clock::universal_time()), | 508 creationTime_(boost::posix_time::microsec_clock::universal_time()), |
498 lastStateChangeTime(creationTime_), | 509 lastStateChangeTime_(creationTime_), |
499 runtime_(boost::posix_time::milliseconds(0)), | 510 runtime_(boost::posix_time::milliseconds(0)), |
500 pauseScheduled_(false), | 511 retryTime_(creationTime_), |
501 lastErrorCode_(ErrorCode_Success), | 512 pauseScheduled_(false) |
502 lastProgress_(0) | |
503 { | 513 { |
504 if (job == NULL) | 514 if (job == NULL) |
505 { | 515 { |
506 throw OrthancException(ErrorCode_NullPointer); | 516 throw OrthancException(ErrorCode_NullPointer); |
507 } | 517 } |
508 } | 518 } |
509 | 519 |
510 const std::string& GetId() const | 520 const std::string& GetId() const |
511 { | 521 { |
512 return id_; | 522 return id_; |
523 } | |
524 | |
525 IJob& GetJob() const | |
526 { | |
527 assert(job_.get() != NULL); | |
528 return *job_; | |
513 } | 529 } |
514 | 530 |
515 void SetPriority(int priority) | 531 void SetPriority(int priority) |
516 { | 532 { |
517 priority_ = priority; | 533 priority_ = priority; |
583 { | 599 { |
584 return retryTime_ <= now; | 600 return retryTime_ <= now; |
585 } | 601 } |
586 } | 602 } |
587 | 603 |
588 class JobLock | 604 JobStatus& GetLastStatus() |
589 { | 605 { |
590 private: | 606 return lastStatus_; |
591 boost::mutex::scoped_lock lock_; | 607 } |
592 JobHandler& handler_; | 608 |
593 | 609 const JobStatus& GetLastStatus() const |
594 public: | 610 { |
595 JobLock(JobHandler& handler) : | 611 return lastStatus_; |
596 lock_(handler.jobMutex_), | 612 } |
597 handler_(handler) | |
598 { | |
599 } | |
600 | |
601 IJob& GetJob() | |
602 { | |
603 return *handler_.job_; | |
604 } | |
605 | |
606 void UpdateStatus() | |
607 { | |
608 handler_.lastProgress_ = handler_.job_->GetProgress(); | |
609 handler_.job_->FormatStatus(handler_.lastStatus_); | |
610 } | |
611 | |
612 void SetLastErrorCode(ErrorCode code) | |
613 { | |
614 handler_.lastErrorCode_ = code; | |
615 } | |
616 }; | |
617 }; | 613 }; |
618 | 614 |
619 | 615 |
620 class JobsRegistry : public boost::noncopyable | 616 class JobsRegistry : public boost::noncopyable |
621 { | 617 { |
769 bool success) | 765 bool success) |
770 { | 766 { |
771 LOG(INFO) << "Job has completed with " << (success ? "success" : "failure") | 767 LOG(INFO) << "Job has completed with " << (success ? "success" : "failure") |
772 << ": " << job.GetId(); | 768 << ": " << job.GetId(); |
773 | 769 |
774 boost::mutex::scoped_lock lock(mutex_); | |
775 CheckInvariants(); | 770 CheckInvariants(); |
776 assert(job.GetState() == JobState_Running); | 771 assert(job.GetState() == JobState_Running); |
777 | 772 |
778 job.SetState(success ? JobState_Success : JobState_Failure); | 773 job.SetState(success ? JobState_Success : JobState_Failure); |
779 | 774 |
787 void MarkRunningAsRetry(JobHandler& job, | 782 void MarkRunningAsRetry(JobHandler& job, |
788 unsigned int timeout) | 783 unsigned int timeout) |
789 { | 784 { |
790 LOG(INFO) << "Job scheduled for retry in " << timeout << "ms: " << job.GetId(); | 785 LOG(INFO) << "Job scheduled for retry in " << timeout << "ms: " << job.GetId(); |
791 | 786 |
792 boost::mutex::scoped_lock lock(mutex_); | |
793 CheckInvariants(); | 787 CheckInvariants(); |
794 | 788 |
795 assert(job.GetState() == JobState_Running && | 789 assert(job.GetState() == JobState_Running && |
796 retryJobs_.find(&job) == retryJobs_.end()); | 790 retryJobs_.find(&job) == retryJobs_.end()); |
797 | 791 |
804 | 798 |
805 void MarkRunningAsPaused(JobHandler& job) | 799 void MarkRunningAsPaused(JobHandler& job) |
806 { | 800 { |
807 LOG(INFO) << "Job paused: " << job.GetId(); | 801 LOG(INFO) << "Job paused: " << job.GetId(); |
808 | 802 |
809 boost::mutex::scoped_lock lock(mutex_); | |
810 CheckInvariants(); | 803 CheckInvariants(); |
811 assert(job.GetState() == JobState_Running); | 804 assert(job.GetState() == JobState_Running); |
812 | 805 |
813 job.SetState(JobState_Paused); | 806 job.SetState(JobState_Paused); |
814 | 807 |
815 CheckInvariants(); | 808 CheckInvariants(); |
816 } | |
817 | |
818 | |
819 JobHandler* WaitPendingJob(unsigned int timeout) | |
820 { | |
821 boost::mutex::scoped_lock lock(mutex_); | |
822 | |
823 while (pendingJobs_.empty()) | |
824 { | |
825 if (timeout == 0) | |
826 { | |
827 pendingJobAvailable_.wait(lock); | |
828 } | |
829 else | |
830 { | |
831 bool success = pendingJobAvailable_.timed_wait | |
832 (lock, boost::posix_time::milliseconds(timeout)); | |
833 if (!success) | |
834 { | |
835 return NULL; | |
836 } | |
837 } | |
838 } | |
839 | |
840 JobHandler* job = pendingJobs_.top(); | |
841 pendingJobs_.pop(); | |
842 | |
843 job->SetState(JobState_Running); | |
844 return job; | |
845 } | 809 } |
846 | 810 |
847 | 811 |
848 public: | 812 public: |
849 JobsRegistry() : | 813 JobsRegistry() : |
1146 | 1110 |
1147 | 1111 |
1148 class RunningJob : public boost::noncopyable | 1112 class RunningJob : public boost::noncopyable |
1149 { | 1113 { |
1150 private: | 1114 private: |
1151 JobsRegistry& that_; | 1115 JobsRegistry& registry_; |
1152 JobHandler* handler_; | 1116 JobHandler* handler_; // Can only be accessed if the registry |
1117 // mutex is locked! | |
1118 IJob* job_; // Will by design be in mutual exclusion, | |
1119 // because only one RunningJob can be | |
1120 // executed at a time on a JobHandler | |
1121 | |
1122 std::string id_; | |
1123 int priority_; | |
1153 JobState targetState_; | 1124 JobState targetState_; |
1154 unsigned int retryTimeout_; | 1125 unsigned int targetRetryTimeout_; |
1155 | 1126 |
1156 public: | 1127 public: |
1157 RunningJob(JobsRegistry& that, | 1128 RunningJob(JobsRegistry& registry, |
1158 unsigned int timeout) : | 1129 unsigned int timeout) : |
1159 that_(that), | 1130 registry_(registry), |
1160 handler_(NULL), | 1131 handler_(NULL), |
1161 targetState_(JobState_Failure), | 1132 targetState_(JobState_Failure), |
1162 retryTimeout_(0) | 1133 targetRetryTimeout_(0) |
1163 { | 1134 { |
1164 handler_ = that_.WaitPendingJob(timeout); | 1135 { |
1136 boost::mutex::scoped_lock lock(registry_.mutex_); | |
1137 | |
1138 while (registry_.pendingJobs_.empty()) | |
1139 { | |
1140 if (timeout == 0) | |
1141 { | |
1142 registry_.pendingJobAvailable_.wait(lock); | |
1143 } | |
1144 else | |
1145 { | |
1146 bool success = registry_.pendingJobAvailable_.timed_wait | |
1147 (lock, boost::posix_time::milliseconds(timeout)); | |
1148 if (!success) | |
1149 { | |
1150 // No pending job | |
1151 return; | |
1152 } | |
1153 } | |
1154 } | |
1155 | |
1156 handler_ = registry_.pendingJobs_.top(); | |
1157 registry_.pendingJobs_.pop(); | |
1158 | |
1159 assert(handler_->GetState() == JobState_Pending); | |
1160 handler_->SetState(JobState_Running); | |
1161 | |
1162 job_ = &handler_->GetJob(); | |
1163 id_ = handler_->GetId(); | |
1164 priority_ = handler_->GetPriority(); | |
1165 } | |
1165 } | 1166 } |
1166 | 1167 |
1167 ~RunningJob() | 1168 ~RunningJob() |
1168 { | 1169 { |
1169 if (IsValid()) | 1170 if (IsValid()) |
1170 { | 1171 { |
1172 boost::mutex::scoped_lock lock(registry_.mutex_); | |
1173 | |
1171 switch (targetState_) | 1174 switch (targetState_) |
1172 { | 1175 { |
1173 case JobState_Failure: | 1176 case JobState_Failure: |
1174 that_.MarkRunningAsCompleted(*handler_, false); | 1177 registry_.MarkRunningAsCompleted(*handler_, false); |
1175 break; | 1178 break; |
1176 | 1179 |
1177 case JobState_Success: | 1180 case JobState_Success: |
1178 that_.MarkRunningAsCompleted(*handler_, true); | 1181 registry_.MarkRunningAsCompleted(*handler_, true); |
1179 break; | 1182 break; |
1180 | 1183 |
1181 case JobState_Paused: | 1184 case JobState_Paused: |
1182 that_.MarkRunningAsPaused(*handler_); | 1185 registry_.MarkRunningAsPaused(*handler_); |
1183 break; | 1186 break; |
1184 | 1187 |
1185 case JobState_Retry: | 1188 case JobState_Retry: |
1186 that_.MarkRunningAsRetry(*handler_, retryTimeout_); | 1189 registry_.MarkRunningAsRetry(*handler_, targetRetryTimeout_); |
1187 break; | 1190 break; |
1188 | 1191 |
1189 default: | 1192 default: |
1190 assert(0); | 1193 assert(0); |
1191 } | 1194 } |
1192 } | 1195 } |
1193 } | 1196 } |
1194 | 1197 |
1195 bool IsValid() const | 1198 bool IsValid() const |
1196 { | 1199 { |
1197 return handler_ != NULL; | 1200 return (handler_ != NULL && |
1201 job_ != NULL); | |
1198 } | 1202 } |
1199 | 1203 |
1200 const std::string& GetId() const | 1204 const std::string& GetId() const |
1201 { | 1205 { |
1202 if (IsValid()) | 1206 if (!IsValid()) |
1203 { | 1207 { |
1204 return handler_->GetId(); | 1208 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
1205 } | 1209 } |
1206 else | 1210 else |
1207 { | 1211 { |
1212 return id_; | |
1213 } | |
1214 } | |
1215 | |
1216 int GetPriority() const | |
1217 { | |
1218 if (!IsValid()) | |
1219 { | |
1208 throw OrthancException(ErrorCode_BadSequenceOfCalls); | 1220 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
1209 } | |
1210 } | |
1211 | |
1212 int GetPriority() const | |
1213 { | |
1214 if (IsValid()) | |
1215 { | |
1216 return handler_->GetPriority(); | |
1217 } | 1221 } |
1218 else | 1222 else |
1219 { | 1223 { |
1224 return priority_; | |
1225 } | |
1226 } | |
1227 | |
1228 bool IsPauseScheduled() | |
1229 { | |
1230 if (!IsValid()) | |
1231 { | |
1220 throw OrthancException(ErrorCode_BadSequenceOfCalls); | 1232 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
1221 } | 1233 } |
1222 } | 1234 else |
1223 | 1235 { |
1224 bool IsPauseScheduled() | 1236 boost::mutex::scoped_lock lock(registry_.mutex_); |
1237 registry_.CheckInvariants(); | |
1238 assert(handler_->GetState() == JobState_Running); | |
1239 | |
1240 return handler_->IsPauseScheduled(); | |
1241 } | |
1242 } | |
1243 | |
1244 void MarkSuccess() | |
1225 { | 1245 { |
1226 if (!IsValid()) | 1246 if (!IsValid()) |
1227 { | 1247 { |
1228 throw OrthancException(ErrorCode_BadSequenceOfCalls); | 1248 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
1229 } | 1249 } |
1230 | 1250 else |
1231 boost::mutex::scoped_lock lock(that_.mutex_); | 1251 { |
1232 that_.CheckInvariants(); | 1252 targetState_ = JobState_Success; |
1233 assert(handler_->GetState() == JobState_Running); | 1253 } |
1234 | 1254 } |
1235 return handler_->IsPauseScheduled(); | 1255 |
1236 } | 1256 void MarkFailure() |
1237 | |
1238 void MarkSuccess() | |
1239 { | 1257 { |
1240 if (!IsValid()) | 1258 if (!IsValid()) |
1241 { | 1259 { |
1242 throw OrthancException(ErrorCode_BadSequenceOfCalls); | 1260 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
1243 } | 1261 } |
1244 | 1262 else |
1245 targetState_ = JobState_Success; | 1263 { |
1246 } | 1264 targetState_ = JobState_Failure; |
1247 | 1265 } |
1248 void MarkFailure() | 1266 } |
1267 | |
1268 void MarkPause() | |
1249 { | 1269 { |
1250 if (!IsValid()) | 1270 if (!IsValid()) |
1251 { | 1271 { |
1252 throw OrthancException(ErrorCode_BadSequenceOfCalls); | 1272 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
1253 } | 1273 } |
1254 | 1274 else |
1255 targetState_ = JobState_Failure; | 1275 { |
1256 } | 1276 targetState_ = JobState_Paused; |
1257 | 1277 } |
1258 void SchedulePause() | 1278 } |
1279 | |
1280 void MarkRetry(unsigned int timeout) | |
1259 { | 1281 { |
1260 if (!IsValid()) | 1282 if (!IsValid()) |
1261 { | 1283 { |
1262 throw OrthancException(ErrorCode_BadSequenceOfCalls); | 1284 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
1263 } | 1285 } |
1264 | 1286 else |
1265 targetState_ = JobState_Paused; | 1287 { |
1266 } | 1288 targetState_ = JobState_Retry; |
1267 | 1289 targetRetryTimeout_ = timeout; |
1268 void MarkRetry(unsigned int timeout) | 1290 } |
1291 } | |
1292 | |
1293 /*void ExecuteStep() | |
1269 { | 1294 { |
1270 if (!IsValid()) | 1295 if (!IsValid()) |
1271 { | 1296 { |
1272 throw OrthancException(ErrorCode_BadSequenceOfCalls); | 1297 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
1273 } | 1298 } |
1274 | 1299 |
1275 targetState_ = JobState_Retry; | 1300 if (IsPauseScheduled()) |
1276 retryTimeout_ = timeout; | |
1277 } | |
1278 | |
1279 void ExecuteStep() | |
1280 { | |
1281 if (!IsValid()) | |
1282 { | |
1283 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1284 } | |
1285 | |
1286 if (handler_->IsPauseScheduled()) | |
1287 { | 1301 { |
1288 targetState_ = JobState_Paused; | 1302 targetState_ = JobState_Paused; |
1289 return; | 1303 return; |
1290 } | 1304 } |
1291 | 1305 |
1292 std::auto_ptr<JobStepResult> result; | 1306 std::auto_ptr<JobStepResult> result; |
1293 | 1307 ErrorCode code; |
1294 { | 1308 |
1295 JobHandler::JobLock lock(*handler_); | 1309 { |
1296 | |
1297 bool ok = false; | 1310 bool ok = false; |
1298 | 1311 |
1299 try | 1312 try |
1300 { | 1313 { |
1301 result.reset(lock.GetJob().ExecuteStep()); | 1314 result.reset(job_->ExecuteStep()); |
1302 lock.UpdateStatus(); | |
1303 ok = true; | 1315 ok = true; |
1316 | |
1317 if (result->GetCode() == JobStepCode_Failure) | |
1318 { | |
1319 code = ErrorCode_InternalError; | |
1320 } | |
1304 } | 1321 } |
1305 catch (OrthancException& e) | 1322 catch (OrthancException& e) |
1306 { | 1323 { |
1307 lock.SetLastErrorCode(e.GetErrorCode()); | 1324 code = e.GetErrorCode(); |
1308 } | 1325 } |
1309 catch (boost::bad_lexical_cast&) | 1326 catch (boost::bad_lexical_cast&) |
1310 { | 1327 { |
1311 lock.SetLastErrorCode(ErrorCode_BadFileFormat); | 1328 code = ErrorCode_BadFileFormat; |
1312 } | 1329 } |
1313 catch (...) | 1330 catch (...) |
1314 { | 1331 { |
1315 lock.SetLastErrorCode(ErrorCode_InternalError); | 1332 code = ErrorCode_InternalError; |
1316 } | 1333 } |
1317 | 1334 |
1318 if (ok) | 1335 if (ok) |
1319 { | 1336 { |
1320 lock.SetLastErrorCode(ErrorCode_Success); | 1337 code = ErrorCode_Success; |
1321 } | 1338 } |
1322 else | 1339 else |
1323 { | 1340 { |
1324 result.reset(new JobStepResult(JobStepStatus_Failure)); | 1341 result.reset(new JobStepResult(JobStepCode_Failure)); |
1325 } | 1342 } |
1326 } | 1343 } |
1327 | 1344 |
1328 switch (result->GetStatus()) | 1345 switch (result->GetCode()) |
1329 { | 1346 { |
1330 case JobStepStatus_Success: | 1347 case JobStepCode_Success: |
1331 targetState_ = JobState_Success; | 1348 targetState_ = JobState_Success; |
1332 break; | 1349 break; |
1333 | 1350 |
1334 case JobStepStatus_Failure: | 1351 case JobStepCode_Failure: |
1335 targetState_ = JobState_Failure; | 1352 targetState_ = JobState_Failure; |
1336 break; | 1353 break; |
1337 | 1354 |
1338 case JobStepStatus_Continue: | 1355 case JobStepCode_Continue: |
1339 targetState_ = JobState_Running; | 1356 targetState_ = JobState_Running; |
1340 break; | 1357 break; |
1341 | 1358 |
1342 case JobStepStatus_Retry: | 1359 case JobStepCode_Retry: |
1343 targetState_ = JobState_Retry; | 1360 targetState_ = JobState_Retry; |
1344 retryTimeout_ = dynamic_cast<RetryResult&>(*result).GetTimeout(); | 1361 targetRetryTimeout_ = dynamic_cast<RetryResult&>(*result).GetTimeout(); |
1345 break; | 1362 break; |
1346 | 1363 |
1347 default: | 1364 default: |
1348 throw OrthancException(ErrorCode_InternalError); | 1365 throw OrthancException(ErrorCode_InternalError); |
1349 } | 1366 } |
1350 } | 1367 }*/ |
1351 }; | 1368 }; |
1352 }; | 1369 }; |
1353 } | 1370 } |
1354 | 1371 |
1355 | 1372 |
1359 private: | 1376 private: |
1360 JobStepResult result_; | 1377 JobStepResult result_; |
1361 | 1378 |
1362 public: | 1379 public: |
1363 DummyJob() : | 1380 DummyJob() : |
1364 result_(Orthanc::JobStepStatus_Success) | 1381 result_(Orthanc::JobStepCode_Success) |
1365 { | 1382 { |
1366 } | 1383 } |
1367 | 1384 |
1368 explicit DummyJob(JobStepResult result) : | 1385 explicit DummyJob(JobStepResult result) : |
1369 result_(result) | 1386 result_(result) |
1631 { | 1648 { |
1632 JobsRegistry::RunningJob job(registry, 0); | 1649 JobsRegistry::RunningJob job(registry, 0); |
1633 ASSERT_TRUE(job.IsValid()); | 1650 ASSERT_TRUE(job.IsValid()); |
1634 | 1651 |
1635 registry.Resubmit(id); | 1652 registry.Resubmit(id); |
1636 job.SchedulePause(); | 1653 job.MarkPause(); |
1637 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Running)); | 1654 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Running)); |
1638 } | 1655 } |
1639 | 1656 |
1640 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Paused)); | 1657 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Paused)); |
1641 | 1658 |