PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
task_scheduler_config.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
17#pragma once
18
19#include <chrono>
20#include <cstdint>
21#include <functional>
22#include <map>
23#include <optional>
24#include <set>
25#include <string>
26#include <variant>
27#include <vector>
28
29namespace kcenon::pacs::workflow {
30
31// =============================================================================
32// Schedule Expression Types
33// =============================================================================
34
42 std::chrono::seconds interval{3600}; // Default: 1 hour
43
45 std::optional<std::chrono::system_clock::time_point> start_at;
46};
47
56 std::string minute{"*"};
57
59 std::string hour{"*"};
60
62 std::string day_of_month{"*"};
63
65 std::string month{"*"};
66
68 std::string day_of_week{"*"};
69
74 [[nodiscard]] static auto every_minutes(int n) -> cron_schedule {
76 s.minute = "*/" + std::to_string(n);
77 return s;
78 }
79
84 [[nodiscard]] static auto every_hours(int n) -> cron_schedule {
86 s.minute = "0";
87 s.hour = "*/" + std::to_string(n);
88 return s;
89 }
90
96 [[nodiscard]] static auto daily_at(int hour, int minute = 0) -> cron_schedule {
98 s.minute = std::to_string(minute);
99 s.hour = std::to_string(hour);
100 return s;
101 }
102
109 [[nodiscard]] static auto weekly_on(int day_of_week, int hour = 0, int minute = 0)
110 -> cron_schedule {
112 s.minute = std::to_string(minute);
113 s.hour = std::to_string(hour);
114 s.day_of_week = std::to_string(day_of_week);
115 return s;
116 }
117
123 [[nodiscard]] static auto parse(const std::string& expr) -> cron_schedule;
124
129 [[nodiscard]] auto to_string() const -> std::string;
130
135 [[nodiscard]] auto is_valid() const noexcept -> bool;
136};
137
143 std::chrono::system_clock::time_point execute_at;
144};
145
149using schedule = std::variant<interval_schedule, cron_schedule, one_time_schedule>;
150
151// =============================================================================
152// Task Types and States
153// =============================================================================
154
158enum class task_type {
159 cleanup,
160 archive,
162 custom
163};
164
168enum class task_state {
169 pending,
170 running,
171 completed,
172 failed,
173 cancelled,
174 paused
175};
176
180[[nodiscard]] inline auto to_string(task_state state) -> std::string {
181 switch (state) {
182 case task_state::pending: return "pending";
183 case task_state::running: return "running";
184 case task_state::completed: return "completed";
185 case task_state::failed: return "failed";
186 case task_state::cancelled: return "cancelled";
187 case task_state::paused: return "paused";
188 default: return "unknown";
189 }
190}
191
195[[nodiscard]] inline auto to_string(task_type type) -> std::string {
196 switch (type) {
197 case task_type::cleanup: return "cleanup";
198 case task_type::archive: return "archive";
199 case task_type::verification: return "verification";
200 case task_type::custom: return "custom";
201 default: return "unknown";
202 }
203}
204
205// =============================================================================
206// Task Execution Records
207// =============================================================================
208
214 std::string execution_id;
215
217 std::string task_id;
218
220 std::chrono::system_clock::time_point started_at;
221
223 std::optional<std::chrono::system_clock::time_point> ended_at;
224
226 task_state state{task_state::pending};
227
229 std::optional<std::string> error_message;
230
232 std::optional<std::string> result_json;
233
238 [[nodiscard]] auto duration() const
239 -> std::optional<std::chrono::milliseconds> {
240 if (ended_at) {
241 return std::chrono::duration_cast<std::chrono::milliseconds>(
242 *ended_at - started_at);
243 }
244 return std::nullopt;
245 }
246};
247
248// =============================================================================
249// Scheduled Task Definition
250// =============================================================================
251
255using task_id = std::string;
256
262using task_callback = std::function<bool()>;
263
269using task_callback_with_result = std::function<std::optional<std::string>()>;
270
277
279 std::string name;
280
282 std::string description;
283
285 task_type type{task_type::custom};
286
289
291 task_state state{task_state::pending};
292
295
297 bool enabled{true};
298
300 int priority{0};
301
303 std::set<std::string> tags;
304
306 std::chrono::seconds timeout{0};
307
309 std::size_t max_retries{0};
310
312 std::chrono::seconds retry_delay{60};
313
315 std::chrono::system_clock::time_point created_at;
316
318 std::chrono::system_clock::time_point updated_at;
319
321 std::optional<std::chrono::system_clock::time_point> next_run_at;
322
324 std::optional<std::chrono::system_clock::time_point> last_run_at;
325
327 std::optional<task_execution_record> last_execution;
328
330 std::size_t execution_count{0};
331
333 std::size_t success_count{0};
334
336 std::size_t failure_count{0};
337};
338
339// =============================================================================
340// Cleanup Task Configuration
341// =============================================================================
342
348 std::chrono::days default_retention{365};
349
351 std::map<std::string, std::chrono::days> modality_retention;
352
354 std::set<std::string> exclude_patterns;
355
357 bool verify_not_locked{true};
358
360 bool dry_run{false};
361
363 std::size_t max_deletions_per_cycle{100};
364
366 bool database_only{false};
367
369 schedule cleanup_schedule{cron_schedule::daily_at(2, 0)}; // 2:00 AM
370
376 [[nodiscard]] auto retention_for(const std::string& modality) const
377 -> std::chrono::days {
378 auto it = modality_retention.find(modality);
379 return it != modality_retention.end() ? it->second : default_retention;
380 }
381};
382
383// =============================================================================
384// Archive Task Configuration
385// =============================================================================
386
397
403 std::chrono::days archive_after{90};
404
406 archive_destination_type destination_type{archive_destination_type::local_path};
407
409 std::string destination;
410
412 std::optional<std::string> credentials_key;
413
415 bool verify_after_archive{true};
416
418 bool delete_after_archive{false};
419
421 bool compress{true};
422
424 int compression_level{6};
425
427 std::size_t max_archives_per_cycle{50};
428
430 schedule archive_schedule{cron_schedule::daily_at(3, 0)}; // 3:00 AM
431};
432
433// =============================================================================
434// Verification Task Configuration
435// =============================================================================
436
442 std::chrono::hours interval{24};
443
445 bool check_checksums{true};
446
448 bool check_db_consistency{true};
449
451 bool check_dicom_structure{false};
452
454 bool repair_on_failure{false};
455
457 std::size_t max_verifications_per_cycle{1000};
458
460 std::string hash_algorithm{"SHA256"};
461
463 schedule verification_schedule{cron_schedule::daily_at(4, 0)}; // 4:00 AM
464};
465
466// =============================================================================
467// Task Scheduler Service Configuration
468// =============================================================================
469
475 bool enabled{true};
476
478 bool auto_start{false};
479
481 std::size_t max_concurrent_tasks{4};
482
484 std::chrono::seconds check_interval{60};
485
487 std::string persistence_path;
488
490 bool restore_on_startup{true};
491
493 std::optional<cleanup_config> cleanup;
494
496 std::optional<archive_config> archive;
497
499 std::optional<verification_config> verification;
500
503 std::function<void(const task_id& id,
504 const task_execution_record& record)>;
506
509 std::function<void(const task_id& id,
510 const std::string& error)>;
512
515 std::function<void(std::size_t tasks_executed,
516 std::size_t tasks_succeeded,
517 std::size_t tasks_failed)>;
519
524 [[nodiscard]] auto is_valid() const noexcept -> bool {
525 return enabled && max_concurrent_tasks > 0;
526 }
527};
528
529// =============================================================================
530// Task Scheduler Statistics
531// =============================================================================
532
538 std::size_t scheduled_tasks{0};
539
541 std::size_t running_tasks{0};
542
544 std::size_t total_executions{0};
545
547 std::size_t successful_executions{0};
548
550 std::size_t failed_executions{0};
551
553 std::size_t cancelled_executions{0};
554
556 std::chrono::milliseconds avg_execution_time{0};
557
559 std::chrono::milliseconds max_execution_time{0};
560
562 std::chrono::seconds uptime{0};
563
565 std::optional<std::chrono::system_clock::time_point> last_cycle_at;
566};
567
568} // namespace kcenon::pacs::workflow
task_state
Task execution state.
@ running
Currently executing.
@ pending
Waiting for scheduled time.
@ completed
Completed successfully.
archive_destination_type
Archive destination type.
std::function< std::optional< std::string >()> task_callback_with_result
Task callback with result details.
task_type
Task type enumeration.
@ archive
Study archival task.
@ cleanup
Storage cleanup task.
@ verification
Data integrity verification.
std::string task_id
Unique task identifier.
std::function< bool()> task_callback
Task callback function type.
std::variant< interval_schedule, cron_schedule, one_time_schedule > schedule
Combined schedule type.
Configuration for archive scheduling.
std::string destination
Destination path or URL.
std::optional< std::string > credentials_key
Credentials (if required)
Configuration for cleanup scheduling.
std::set< std::string > exclude_patterns
Study description patterns to exclude from cleanup.
std::map< std::string, std::chrono::days > modality_retention
Modality-specific retention periods.
auto retention_for(const std::string &modality) const -> std::chrono::days
Get retention period for a modality.
static auto every_hours(int n) -> cron_schedule
Create a schedule that runs every N hours.
static auto parse(const std::string &expr) -> cron_schedule
Parse a cron expression string.
std::string minute
Minute (0-59, or "*")
std::string month
Month (1-12, or "*")
std::string day_of_month
Day of month (1-31, or "*")
static auto every_minutes(int n) -> cron_schedule
Create a schedule that runs every N minutes.
auto to_string() const -> std::string
Convert to cron expression string.
std::string hour
Hour (0-23, or "*")
std::string day_of_week
Day of week (0-6, Sunday=0, or "*")
auto is_valid() const noexcept -> bool
Check if the schedule is valid.
static auto daily_at(int hour, int minute=0) -> cron_schedule
Create a daily schedule at specific time.
static auto weekly_on(int day_of_week, int hour=0, int minute=0) -> cron_schedule
Create a weekly schedule.
std::chrono::seconds interval
Interval between executions.
std::optional< std::chrono::system_clock::time_point > start_at
Optional start time for first execution.
One-time execution at specific time.
std::chrono::system_clock::time_point execute_at
Execution time.
std::chrono::system_clock::time_point created_at
Creation time.
std::optional< task_execution_record > last_execution
Last execution result.
std::optional< std::chrono::system_clock::time_point > next_run_at
Next scheduled execution time.
std::set< std::string > tags
Tags for categorization.
std::optional< std::chrono::system_clock::time_point > last_run_at
Last execution time.
std::chrono::system_clock::time_point updated_at
Last modification time.
task_callback_with_result callback
Task callback.
std::string name
Human-readable task name.
schedule task_schedule
Schedule for execution.
Statistics for task scheduler operations.
std::optional< std::chrono::system_clock::time_point > last_cycle_at
Last cycle time.
auto duration() const -> std::optional< std::chrono::milliseconds >
Get execution duration.
std::optional< std::string > error_message
Error message (if failed)
std::optional< std::string > result_json
Execution result details (JSON)
std::optional< std::chrono::system_clock::time_point > ended_at
End time (if completed)
std::chrono::system_clock::time_point started_at
Start time.
std::string execution_id
Execution ID (unique per execution)
Configuration for the task scheduler service.
std::function< void(std::size_t tasks_executed, std::size_t tasks_succeeded, std::size_t tasks_failed)> cycle_complete_callback
Callback when scheduler cycle completes.
std::function< void(const task_id &id, const std::string &error)> task_error_callback
Callback when any task fails.
std::optional< verification_config > verification
Verification configuration.
std::function< void(const task_id &id, const task_execution_record &record)> task_complete_callback
Callback when any task completes.
std::string persistence_path
Path to persist scheduled tasks (empty = no persistence)
std::optional< cleanup_config > cleanup
Cleanup configuration.
auto is_valid() const noexcept -> bool
Check if configuration is valid.
std::optional< archive_config > archive
Archive configuration.
Configuration for verification scheduling.