PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
prefetch_manager.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
19#pragma once
20
24
25#include <atomic>
26#include <chrono>
27#include <condition_variable>
28#include <future>
29#include <memory>
30#include <mutex>
31#include <optional>
32#include <shared_mutex>
33#include <string>
34#include <string_view>
35#include <thread>
36#include <unordered_set>
37#include <vector>
38
39// Forward declarations
40namespace kcenon::pacs::storage {
41class prefetch_repository;
42class prefetch_rule_repository;
43class prefetch_history_repository;
44}
45
47class worklist_scu;
48}
49
51class dicom_dataset;
52}
53
54namespace kcenon::pacs::client {
55
56// Forward declarations
57class remote_node_manager;
58class job_manager;
59
61 std::shared_ptr<storage::prefetch_rule_repository> rules;
62 std::shared_ptr<storage::prefetch_history_repository> history;
63};
64
65// =============================================================================
66// Prefetch Manager
67// =============================================================================
68
112public:
113 // =========================================================================
114 // Construction / Destruction
115 // =========================================================================
116
126 explicit prefetch_manager(
127 prefetch_repositories repositories,
128 std::shared_ptr<remote_node_manager> node_manager,
129 std::shared_ptr<job_manager> job_manager,
130 std::shared_ptr<services::worklist_scu> worklist_scu = nullptr,
131 std::shared_ptr<di::ILogger> logger = nullptr);
132
143 explicit prefetch_manager(
145 prefetch_repositories repositories,
146 std::shared_ptr<remote_node_manager> node_manager,
147 std::shared_ptr<job_manager> job_manager,
148 std::shared_ptr<services::worklist_scu> worklist_scu = nullptr,
149 std::shared_ptr<di::ILogger> logger = nullptr);
150
162 explicit prefetch_manager(
163 std::shared_ptr<storage::prefetch_repository> repo,
164 std::shared_ptr<remote_node_manager> node_manager,
165 std::shared_ptr<job_manager> job_manager,
166 std::shared_ptr<services::worklist_scu> worklist_scu = nullptr,
167 std::shared_ptr<di::ILogger> logger = nullptr);
168
181 explicit prefetch_manager(
183 std::shared_ptr<storage::prefetch_repository> repo,
184 std::shared_ptr<remote_node_manager> node_manager,
185 std::shared_ptr<job_manager> job_manager,
186 std::shared_ptr<services::worklist_scu> worklist_scu = nullptr,
187 std::shared_ptr<di::ILogger> logger = nullptr);
188
193
194 // Non-copyable, non-movable (due to internal threading)
196 auto operator=(const prefetch_manager&) -> prefetch_manager& = delete;
199
200 // =========================================================================
201 // Rule Management
202 // =========================================================================
203
210 [[nodiscard]] auto add_rule(const prefetch_rule& rule) -> kcenon::pacs::VoidResult;
211
218 [[nodiscard]] auto update_rule(const prefetch_rule& rule) -> kcenon::pacs::VoidResult;
219
226 [[nodiscard]] auto remove_rule(std::string_view rule_id) -> kcenon::pacs::VoidResult;
227
234 [[nodiscard]] auto get_rule(std::string_view rule_id) const
235 -> std::optional<prefetch_rule>;
236
242 [[nodiscard]] auto list_rules() const -> std::vector<prefetch_rule>;
243
244 // =========================================================================
245 // Worklist-Driven Prefetch
246 // =========================================================================
247
256 void process_worklist(const std::vector<core::dicom_dataset>& worklist_items);
257
264 [[nodiscard]] auto process_worklist_async(
265 const std::vector<core::dicom_dataset>& worklist_items) -> std::future<void>;
266
267 // =========================================================================
268 // Prior Study Prefetch
269 // =========================================================================
270
282 [[nodiscard]] auto prefetch_priors(
283 std::string_view patient_id,
284 std::string_view current_modality,
285 std::optional<std::string_view> body_part = std::nullopt) -> prefetch_result;
286
295 [[nodiscard]] auto prefetch_priors_async(
296 std::string_view patient_id,
297 std::string_view current_modality,
298 std::optional<std::string_view> body_part = std::nullopt)
299 -> std::future<prefetch_result>;
300
301 // =========================================================================
302 // Manual Prefetch
303 // =========================================================================
304
312 [[nodiscard]] auto prefetch_study(
313 std::string_view source_node_id,
314 std::string_view study_uid) -> std::string;
315
324 [[nodiscard]] auto prefetch_patient(
325 std::string_view source_node_id,
326 std::string_view patient_id,
327 std::chrono::hours lookback = std::chrono::hours{8760}) -> std::string;
328
329 // =========================================================================
330 // Scheduler Control
331 // =========================================================================
332
339 void start_scheduler();
340
346 void stop_scheduler();
347
353 [[nodiscard]] auto is_scheduler_running() const noexcept -> bool;
354
355 // =========================================================================
356 // Worklist Monitor Control
357 // =========================================================================
358
366 void start_worklist_monitor(std::string_view worklist_node_id);
367
374
380 [[nodiscard]] auto is_worklist_monitor_running() const noexcept -> bool;
381
382 // =========================================================================
383 // Status and Statistics
384 // =========================================================================
385
391 [[nodiscard]] auto pending_prefetches() const -> size_t;
392
398 [[nodiscard]] auto completed_today() const -> size_t;
399
405 [[nodiscard]] auto failed_today() const -> size_t;
406
413 [[nodiscard]] auto get_rule_statistics(std::string_view rule_id) const
415
416 // =========================================================================
417 // Configuration
418 // =========================================================================
419
425 [[nodiscard]] auto config() const noexcept -> const prefetch_manager_config&;
426
432 void set_config(prefetch_manager_config new_config);
433
434private:
435 // =========================================================================
436 // Private Implementation
437 // =========================================================================
438
439 struct impl;
440 std::unique_ptr<impl> impl_;
441};
442
443} // namespace kcenon::pacs::client
void stop_worklist_monitor()
Stop the worklist monitor.
prefetch_manager(prefetch_manager &&)=delete
auto config() const noexcept -> const prefetch_manager_config &
Get current configuration.
auto prefetch_study(std::string_view source_node_id, std::string_view study_uid) -> std::string
Prefetch a specific study.
auto prefetch_patient(std::string_view source_node_id, std::string_view patient_id, std::chrono::hours lookback=std::chrono::hours{8760}) -> std::string
Prefetch all studies for a patient.
auto is_scheduler_running() const noexcept -> bool
Check if scheduler is running.
auto get_rule(std::string_view rule_id) const -> std::optional< prefetch_rule >
Get a rule by ID.
auto pending_prefetches() const -> size_t
Get number of pending prefetch operations.
auto completed_today() const -> size_t
Get number of prefetches completed today.
void process_worklist(const std::vector< core::dicom_dataset > &worklist_items)
Process worklist items and trigger prefetch.
prefetch_manager(prefetch_repositories repositories, std::shared_ptr< remote_node_manager > node_manager, std::shared_ptr< job_manager > job_manager, std::shared_ptr< services::worklist_scu > worklist_scu=nullptr, std::shared_ptr< di::ILogger > logger=nullptr)
Construct a prefetch manager from split repositories.
auto failed_today() const -> size_t
Get number of prefetches failed today.
auto remove_rule(std::string_view rule_id) -> kcenon::pacs::VoidResult
Remove a prefetch rule.
void set_config(prefetch_manager_config new_config)
Update configuration.
auto prefetch_priors_async(std::string_view patient_id, std::string_view current_modality, std::optional< std::string_view > body_part=std::nullopt) -> std::future< prefetch_result >
Prefetch prior studies asynchronously.
void start_worklist_monitor(std::string_view worklist_node_id)
Start the worklist monitor.
auto list_rules() const -> std::vector< prefetch_rule >
List all prefetch rules.
auto prefetch_priors(std::string_view patient_id, std::string_view current_modality, std::optional< std::string_view > body_part=std::nullopt) -> prefetch_result
Prefetch prior studies for a patient.
auto operator=(const prefetch_manager &) -> prefetch_manager &=delete
auto is_worklist_monitor_running() const noexcept -> bool
Check if worklist monitor is running.
~prefetch_manager()
Destructor - stops scheduler and monitor if running.
auto get_rule_statistics(std::string_view rule_id) const -> prefetch_rule_statistics
Get statistics for a specific rule.
auto add_rule(const prefetch_rule &rule) -> kcenon::pacs::VoidResult
Add a new prefetch rule.
auto operator=(prefetch_manager &&) -> prefetch_manager &=delete
auto update_rule(const prefetch_rule &rule) -> kcenon::pacs::VoidResult
Update an existing prefetch rule.
auto process_worklist_async(const std::vector< core::dicom_dataset > &worklist_items) -> std::future< void >
Process worklist items asynchronously.
prefetch_manager(const prefetch_manager &)=delete
void start_scheduler()
Start the scheduler for cron-based rules.
Logger interface for dependency injection.
@ body_part
(0018,0015) Body Part Examined
Types and structures for prefetch manager.
Result<T> type aliases and helpers for PACS system.
Configuration for the prefetch manager.
std::shared_ptr< storage::prefetch_history_repository > history
std::shared_ptr< storage::prefetch_rule_repository > rules
Result of a prefetch operation.
Rule defining when and how to prefetch DICOM data.