PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
kcenon::pacs::client::prefetch_manager Class Reference

#include <prefetch_manager.h>

Collaboration diagram for kcenon::pacs::client::prefetch_manager:
Collaboration graph

Classes

struct  impl
 

Public Member Functions

 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.
 
 prefetch_manager (const prefetch_manager_config &config, 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 with custom configuration and split repositories.
 
 prefetch_manager (std::shared_ptr< storage::prefetch_repository > repo, 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 with dependencies.
 
 prefetch_manager (const prefetch_manager_config &config, std::shared_ptr< storage::prefetch_repository > repo, 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 with custom configuration.
 
 ~prefetch_manager ()
 Destructor - stops scheduler and monitor if running.
 
 prefetch_manager (const prefetch_manager &)=delete
 
auto operator= (const prefetch_manager &) -> prefetch_manager &=delete
 
 prefetch_manager (prefetch_manager &&)=delete
 
auto operator= (prefetch_manager &&) -> prefetch_manager &=delete
 
auto add_rule (const prefetch_rule &rule) -> kcenon::pacs::VoidResult
 Add a new prefetch rule.
 
auto update_rule (const prefetch_rule &rule) -> kcenon::pacs::VoidResult
 Update an existing prefetch rule.
 
auto remove_rule (std::string_view rule_id) -> kcenon::pacs::VoidResult
 Remove a prefetch rule.
 
auto get_rule (std::string_view rule_id) const -> std::optional< prefetch_rule >
 Get a rule by ID.
 
auto list_rules () const -> std::vector< prefetch_rule >
 List all prefetch rules.
 
void process_worklist (const std::vector< core::dicom_dataset > &worklist_items)
 Process worklist items and trigger prefetch.
 
auto process_worklist_async (const std::vector< core::dicom_dataset > &worklist_items) -> std::future< void >
 Process worklist items asynchronously.
 
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 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.
 
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.
 
void start_scheduler ()
 Start the scheduler for cron-based rules.
 
void stop_scheduler ()
 Stop the scheduler.
 
auto is_scheduler_running () const noexcept -> bool
 Check if scheduler is running.
 
void start_worklist_monitor (std::string_view worklist_node_id)
 Start the worklist monitor.
 
void stop_worklist_monitor ()
 Stop the worklist monitor.
 
auto is_worklist_monitor_running () const noexcept -> bool
 Check if worklist monitor is running.
 
auto pending_prefetches () const -> size_t
 Get number of pending prefetch operations.
 
auto completed_today () const -> size_t
 Get number of prefetches completed today.
 
auto failed_today () const -> size_t
 Get number of prefetches failed today.
 
auto get_rule_statistics (std::string_view rule_id) const -> prefetch_rule_statistics
 Get statistics for a specific rule.
 
auto config () const noexcept -> const prefetch_manager_config &
 Get current configuration.
 
void set_config (prefetch_manager_config new_config)
 Update configuration.
 

Private Attributes

std::unique_ptr< implimpl_
 

Detailed Description

Definition at line 111 of file prefetch_manager.h.

Constructor & Destructor Documentation

◆ prefetch_manager() [1/6]

kcenon::pacs::client::prefetch_manager::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 )
explicit

Construct a prefetch manager from split repositories.

Parameters
repositoriesSplit prefetch repositories for rules and history
node_managerRemote node manager for DICOM operations (required)
job_managerJob manager for async operations (required)
worklist_scuWorklist SCU for MWL queries (optional)
loggerLogger instance (optional, defaults to NullLogger)
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 394 of file prefetch_manager.cpp.

401 prefetch_manager_config{},
402 std::move(repositories),
403 std::move(node_manager),
404 std::move(job_manager),
405 std::move(worklist_scu),
406 std::move(logger)) {}
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.

◆ prefetch_manager() [2/6]

kcenon::pacs::client::prefetch_manager::prefetch_manager ( const prefetch_manager_config & config,
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 )
explicit

Construct with custom configuration and split repositories.

Parameters
configManager configuration
repositoriesSplit prefetch repositories for rules and history
node_managerRemote node manager for DICOM operations (required)
job_managerJob manager for async operations (required)
worklist_scuWorklist SCU for MWL queries (optional)
loggerLogger instance (optional, defaults to NullLogger)

Definition at line 408 of file prefetch_manager.cpp.

415 : impl_(std::make_unique<impl>()) {
417 impl_->repositories = std::move(repositories);
418 impl_->node_manager = std::move(node_manager);
419 impl_->job_mgr = std::move(job_manager);
420 impl_->worklist_scu = std::move(worklist_scu);
421 impl_->logger = logger ? std::move(logger) : std::make_shared<di::NullLogger>();
422
424}
auto config() const noexcept -> const prefetch_manager_config &
Get current configuration.
std::shared_ptr< services::worklist_scu > worklist_scu
std::shared_ptr< remote_node_manager > node_manager

References config(), kcenon::pacs::client::prefetch_manager::impl::config, impl_, kcenon::pacs::client::prefetch_manager::impl::job_mgr, kcenon::pacs::client::prefetch_manager::impl::load_rules_from_repo(), kcenon::pacs::client::prefetch_manager::impl::logger, kcenon::pacs::client::prefetch_manager::impl::node_manager, kcenon::pacs::client::prefetch_manager::impl::repositories, and kcenon::pacs::client::prefetch_manager::impl::worklist_scu.

Here is the call graph for this function:

◆ prefetch_manager() [3/6]

kcenon::pacs::client::prefetch_manager::prefetch_manager ( std::shared_ptr< storage::prefetch_repository > repo,
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 )
explicit

Construct a prefetch manager with dependencies.

Compatibility-only overload. Prefer split repositories for new wiring.

Parameters
repoPrefetch repository for persistence (required)
node_managerRemote node manager for DICOM operations (required)
job_managerJob manager for async operations (required)
worklist_scuWorklist SCU for MWL queries (optional)
loggerLogger instance (optional, defaults to NullLogger)

Definition at line 426 of file prefetch_manager.cpp.

433 prefetch_manager_config{},
434 std::move(repo),
435 std::move(node_manager),
436 std::move(job_manager),
437 std::move(worklist_scu),
438 std::move(logger)) {}

◆ prefetch_manager() [4/6]

kcenon::pacs::client::prefetch_manager::prefetch_manager ( const prefetch_manager_config & config,
std::shared_ptr< storage::prefetch_repository > repo,
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 )
explicit

Construct with custom configuration.

Compatibility-only overload. Prefer split repositories for new wiring.

Parameters
configManager configuration
repoPrefetch repository for persistence (required)
node_managerRemote node manager for DICOM operations (required)
job_managerJob manager for async operations (required)
worklist_scuWorklist SCU for MWL queries (optional)
loggerLogger instance (optional, defaults to NullLogger)

Definition at line 440 of file prefetch_manager.cpp.

447 : impl_(std::make_unique<impl>()) {
449 impl_->compatibility_repo = std::move(repo);
450 impl_->node_manager = std::move(node_manager);
451 impl_->job_mgr = std::move(job_manager);
452 impl_->worklist_scu = std::move(worklist_scu);
453 impl_->logger = logger ? std::move(logger) : std::make_shared<di::NullLogger>();
454
455 // Initialize tables if repository exists
457 [[maybe_unused]] auto result = impl_->compatibility_repo->initialize_tables();
458 }
459
460 // Load rules from repository
462}
std::shared_ptr< storage::prefetch_repository > compatibility_repo

References kcenon::pacs::client::prefetch_manager::impl::compatibility_repo, config(), kcenon::pacs::client::prefetch_manager::impl::config, impl_, kcenon::pacs::client::prefetch_manager::impl::job_mgr, kcenon::pacs::client::prefetch_manager::impl::load_rules_from_repo(), kcenon::pacs::client::prefetch_manager::impl::logger, kcenon::pacs::client::prefetch_manager::impl::node_manager, and kcenon::pacs::client::prefetch_manager::impl::worklist_scu.

Here is the call graph for this function:

◆ ~prefetch_manager()

kcenon::pacs::client::prefetch_manager::~prefetch_manager ( )

Destructor - stops scheduler and monitor if running.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 464 of file prefetch_manager.cpp.

464 {
467}
void stop_worklist_monitor()
Stop the worklist monitor.

References stop_scheduler(), and stop_worklist_monitor().

Here is the call graph for this function:

◆ prefetch_manager() [5/6]

kcenon::pacs::client::prefetch_manager::prefetch_manager ( const prefetch_manager & )
delete

◆ prefetch_manager() [6/6]

kcenon::pacs::client::prefetch_manager::prefetch_manager ( prefetch_manager && )
delete

Member Function Documentation

◆ add_rule()

kcenon::pacs::VoidResult kcenon::pacs::client::prefetch_manager::add_rule ( const prefetch_rule & rule) -> kcenon::pacs::VoidResult
nodiscard

Add a new prefetch rule.

Parameters
ruleThe rule to add
Returns
VoidResult indicating success or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 473 of file prefetch_manager.cpp.

473 {
474 prefetch_rule new_rule = rule;
475 if (new_rule.rule_id.empty()) {
476 new_rule.rule_id = generate_uuid();
477 }
478
479 // Save to repository
480 #ifdef PACS_WITH_DATABASE_SYSTEM
481 if (impl_->repositories.rules) {
482 auto result = impl_->repositories.rules->save(new_rule);
483 if (result.is_err()) {
484 return result.error();
485 }
486 } else if (impl_->compatibility_repo) {
487 auto result = impl_->compatibility_repo->save_rule(new_rule);
488 if (result.is_err()) {
489 return result;
490 }
491 }
492 #else
494 auto result = impl_->compatibility_repo->save_rule(new_rule);
495 if (result.is_err()) {
496 return result;
497 }
498 }
499 #endif
500
501 // Update cache
502 {
503 std::unique_lock lock(impl_->rules_mutex);
504 impl_->rules_cache.push_back(new_rule);
505 }
506
507 impl_->logger->info_fmt("Added prefetch rule: {} ({})", new_rule.name, new_rule.rule_id);
508 return kcenon::common::ok();
509}
std::shared_ptr< storage::prefetch_rule_repository > rules

References kcenon::pacs::client::prefetch_manager::impl::compatibility_repo, impl_, kcenon::pacs::client::prefetch_manager::impl::logger, kcenon::pacs::client::prefetch_rule::name, kcenon::pacs::client::prefetch_manager::impl::repositories, kcenon::pacs::client::prefetch_rule::rule_id, kcenon::pacs::client::prefetch_repositories::rules, kcenon::pacs::client::prefetch_manager::impl::rules_cache, and kcenon::pacs::client::prefetch_manager::impl::rules_mutex.

◆ completed_today()

size_t kcenon::pacs::client::prefetch_manager::completed_today ( ) const -> size_t
nodiscard

Get number of prefetches completed today.

Returns
Number of successful prefetches today
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 863 of file prefetch_manager.cpp.

863 {
864 #ifdef PACS_WITH_DATABASE_SYSTEM
866 auto result =
867 impl_->repositories.history->count_by_status_on_current_date("completed");
868 return result.is_ok() ? result.value() : 0;
869 }
870 #endif
872 return impl_->compatibility_repo->count_completed_today();
873 }
874 return 0;
875}
std::shared_ptr< storage::prefetch_history_repository > history

References kcenon::pacs::client::prefetch_manager::impl::compatibility_repo, kcenon::pacs::client::prefetch_repositories::history, impl_, and kcenon::pacs::client::prefetch_manager::impl::repositories.

◆ config()

const prefetch_manager_config & kcenon::pacs::client::prefetch_manager::config ( ) const -> const prefetch_manager_config&
nodiscardnoexcept

Get current configuration.

Returns
Current manager configuration
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 908 of file prefetch_manager.cpp.

908 {
909 return impl_->config;
910}

References kcenon::pacs::client::prefetch_manager::impl::config, and impl_.

Referenced by prefetch_manager(), and prefetch_manager().

Here is the caller graph for this function:

◆ failed_today()

size_t kcenon::pacs::client::prefetch_manager::failed_today ( ) const -> size_t
nodiscard

Get number of prefetches failed today.

Returns
Number of failed prefetches today
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 877 of file prefetch_manager.cpp.

877 {
878 #ifdef PACS_WITH_DATABASE_SYSTEM
880 auto result =
881 impl_->repositories.history->count_by_status_on_current_date("failed");
882 return result.is_ok() ? result.value() : 0;
883 }
884 #endif
886 return impl_->compatibility_repo->count_failed_today();
887 }
888 return 0;
889}

References kcenon::pacs::client::prefetch_manager::impl::compatibility_repo, kcenon::pacs::client::prefetch_repositories::history, impl_, and kcenon::pacs::client::prefetch_manager::impl::repositories.

◆ get_rule()

std::optional< prefetch_rule > kcenon::pacs::client::prefetch_manager::get_rule ( std::string_view rule_id) const -> std::optional<prefetch_rule>
nodiscard

Get a rule by ID.

Parameters
rule_idID of the rule to retrieve
Returns
Optional containing the rule if found
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 589 of file prefetch_manager.cpp.

589 {
590 std::shared_lock lock(impl_->rules_mutex);
591 for (const auto& rule : impl_->rules_cache) {
592 if (rule.rule_id == rule_id) {
593 return rule;
594 }
595 }
596 return std::nullopt;
597}

References impl_, kcenon::pacs::client::prefetch_manager::impl::rules_cache, and kcenon::pacs::client::prefetch_manager::impl::rules_mutex.

Referenced by get_rule_statistics().

Here is the caller graph for this function:

◆ get_rule_statistics()

prefetch_rule_statistics kcenon::pacs::client::prefetch_manager::get_rule_statistics ( std::string_view rule_id) const -> prefetch_rule_statistics
nodiscard

Get statistics for a specific rule.

Parameters
rule_idRule ID to get statistics for
Returns
Statistics for the rule
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 891 of file prefetch_manager.cpp.

892 {
893 prefetch_rule_statistics stats;
894
895 auto rule = get_rule(rule_id);
896 if (rule) {
897 stats.triggered_count = rule->triggered_count;
898 stats.studies_prefetched = rule->studies_prefetched;
899 }
900
901 return stats;
902}
auto get_rule(std::string_view rule_id) const -> std::optional< prefetch_rule >
Get a rule by ID.

References get_rule().

Here is the call graph for this function:

◆ is_scheduler_running()

bool kcenon::pacs::client::prefetch_manager::is_scheduler_running ( ) const -> bool
nodiscardnoexcept

Check if scheduler is running.

Returns
true if the scheduler is active
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 809 of file prefetch_manager.cpp.

809 {
810 return impl_->scheduler_running.load();
811}

References impl_, and kcenon::pacs::client::prefetch_manager::impl::scheduler_running.

◆ is_worklist_monitor_running()

bool kcenon::pacs::client::prefetch_manager::is_worklist_monitor_running ( ) const -> bool
nodiscardnoexcept

Check if worklist monitor is running.

Returns
true if the worklist monitor is active
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 851 of file prefetch_manager.cpp.

851 {
852 return impl_->worklist_monitor_running.load();
853}

References impl_, and kcenon::pacs::client::prefetch_manager::impl::worklist_monitor_running.

◆ list_rules()

std::vector< prefetch_rule > kcenon::pacs::client::prefetch_manager::list_rules ( ) const -> std::vector<prefetch_rule>
nodiscard

◆ operator=() [1/2]

auto kcenon::pacs::client::prefetch_manager::operator= ( const prefetch_manager & ) -> prefetch_manager &=delete
delete

◆ operator=() [2/2]

auto kcenon::pacs::client::prefetch_manager::operator= ( prefetch_manager && ) -> prefetch_manager &=delete
delete

◆ pending_prefetches()

size_t kcenon::pacs::client::prefetch_manager::pending_prefetches ( ) const -> size_t
nodiscard

Get number of pending prefetch operations.

Returns
Number of prefetches currently queued
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 859 of file prefetch_manager.cpp.

859 {
860 return impl_->pending_count.load();
861}

References impl_, and kcenon::pacs::client::prefetch_manager::impl::pending_count.

◆ prefetch_patient()

std::string kcenon::pacs::client::prefetch_manager::prefetch_patient ( std::string_view source_node_id,
std::string_view patient_id,
std::chrono::hours lookback = std::chrono::hours{8760} ) -> std::string
nodiscard

Prefetch all studies for a patient.

Parameters
source_node_idSource node to retrieve from
patient_idPatient ID to prefetch studies for
lookbackLookback period (default: 1 year)
Returns
Job ID for tracking the prefetch operation
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 754 of file prefetch_manager.cpp.

757 {
758 (void)lookback; // Reserved for future time-based filtering
759 // Create prefetch job for the patient
760 if (impl_->job_mgr) {
761 auto job_id = impl_->job_mgr->create_prefetch_job(
762 source_node_id, patient_id, job_priority::low);
763
764 impl_->logger->info_fmt("Created prefetch job {} for patient {}",
765 job_id, std::string(patient_id));
766 return job_id;
767 }
768
769 return "";
770}
@ low
Background operations.

References impl_, kcenon::pacs::client::prefetch_manager::impl::job_mgr, kcenon::pacs::client::prefetch_manager::impl::logger, and kcenon::pacs::client::low.

◆ prefetch_priors()

prefetch_result kcenon::pacs::client::prefetch_manager::prefetch_priors ( std::string_view patient_id,
std::string_view current_modality,
std::optional< std::string_view > body_part = std::nullopt ) -> prefetch_result
nodiscard

Prefetch prior studies for a patient.

Searches configured source nodes for prior studies matching the patient and modality criteria.

Parameters
patient_idPatient ID to search for
current_modalityCurrent exam modality
body_partOptional body part filter
Returns
Prefetch result with statistics
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 649 of file prefetch_manager.cpp.

652 {
653 auto start_time = std::chrono::steady_clock::now();
654 prefetch_result result;
655 result.patient_id = std::string(patient_id);
656
657 // Find matching prior study rules
658 auto rules = impl_->get_matching_rules(
660 std::string(current_modality),
661 body_part ? std::string(*body_part) : "",
662 "");
663
664 if (rules.empty()) {
665 impl_->logger->debug_fmt("No prior study rules match for patient {} modality {}",
666 std::string(patient_id), std::string(current_modality));
667 return result;
668 }
669
670 // Use the first matching rule (or could combine multiple)
671 const auto& rule = rules.front();
672
673 // Query prior studies from each source node
674 for (const auto& source_node_id : rule.source_node_ids) {
675 auto node = impl_->node_manager->get_node(source_node_id);
676 if (!node) {
677 impl_->logger->warn_fmt("Source node {} not found", source_node_id);
678 continue;
679 }
680
681 // Query for prior studies
682 // In production, this would use query_scu to search for studies
683 // For now, create prefetch jobs based on rule configuration
684
685 // Record that we attempted prefetch
686 impl_->logger->info_fmt("Prefetching priors for patient {} from node {}",
687 std::string(patient_id), source_node_id);
688 }
689
690 auto end_time = std::chrono::steady_clock::now();
691 result.elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
692 end_time - start_time);
693
694 return result;
695}
@ body_part
(0018,0015) Body Part Examined
@ prior_studies
Fetch prior studies for patient.
std::vector< prefetch_rule > get_matching_rules(prefetch_trigger trigger, const std::string &modality, const std::string &body_part, const std::string &station_ae)

References kcenon::pacs::client::body_part, kcenon::pacs::client::prefetch_result::elapsed, kcenon::pacs::client::prefetch_manager::impl::get_matching_rules(), impl_, kcenon::pacs::client::prefetch_manager::impl::logger, kcenon::pacs::client::prefetch_manager::impl::node_manager, kcenon::pacs::client::prefetch_result::patient_id, and kcenon::pacs::client::prior_studies.

Referenced by prefetch_priors_async(), and process_worklist().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ prefetch_priors_async()

std::future< prefetch_result > kcenon::pacs::client::prefetch_manager::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>
nodiscard

Prefetch prior studies asynchronously.

Parameters
patient_idPatient ID to search for
current_modalityCurrent exam modality
body_partOptional body part filter
Returns
Future containing prefetch result
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 697 of file prefetch_manager.cpp.

700 {
701 std::string pid(patient_id);
702 std::string mod(current_modality);
703 std::optional<std::string> bp = body_part ?
704 std::optional<std::string>(std::string(*body_part)) : std::nullopt;
705
706 return std::async(std::launch::async, [this, pid, mod, bp]() {
707 return prefetch_priors(pid, mod, bp ? std::optional<std::string_view>(*bp) : std::nullopt);
708 });
709}
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.

References kcenon::pacs::client::body_part, and prefetch_priors().

Here is the call graph for this function:

◆ prefetch_study()

std::string kcenon::pacs::client::prefetch_manager::prefetch_study ( std::string_view source_node_id,
std::string_view study_uid ) -> std::string
nodiscard

Prefetch a specific study.

Parameters
source_node_idSource node to retrieve from
study_uidStudy Instance UID to prefetch
Returns
Job ID for tracking the prefetch operation
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 715 of file prefetch_manager.cpp.

717 {
718 // Check deduplication
720 if (impl_->is_study_pending(std::string(study_uid))) {
721 impl_->logger->debug_fmt("Study {} already pending", std::string(study_uid));
722 return "";
723 }
724 if (impl_->is_study_local(study_uid)) {
725 impl_->logger->debug_fmt("Study {} already local", std::string(study_uid));
726 return "";
727 }
728 }
729
730 // Mark as pending
731 impl_->mark_study_pending(std::string(study_uid));
732
733 // Create retrieve job
734 if (impl_->job_mgr) {
735 auto job_id = impl_->job_mgr->create_retrieve_job(
736 source_node_id, study_uid, std::nullopt, job_priority::low);
737
738 // Record history
740 "", // patient_id unknown
741 std::string(study_uid),
742 "", // no rule
743 std::string(source_node_id),
744 job_id,
745 "pending");
746
747 impl_->logger->info_fmt("Created prefetch job {} for study {}", job_id, std::string(study_uid));
748 return job_id;
749 }
750
751 return "";
752}
bool is_study_local(std::string_view study_uid) const
bool is_study_pending(const std::string &study_uid)
void mark_study_pending(const std::string &study_uid)
void record_prefetch_history(const std::string &patient_id, const std::string &study_uid, const std::string &rule_id, const std::string &source_node_id, const std::string &job_id, const std::string &status)
bool deduplicate_requests
Deduplicate pending requests.

References kcenon::pacs::client::prefetch_manager::impl::config, kcenon::pacs::client::prefetch_manager_config::deduplicate_requests, impl_, kcenon::pacs::client::prefetch_manager::impl::is_study_local(), kcenon::pacs::client::prefetch_manager::impl::is_study_pending(), kcenon::pacs::client::prefetch_manager::impl::job_mgr, kcenon::pacs::client::prefetch_manager::impl::logger, kcenon::pacs::client::low, kcenon::pacs::client::prefetch_manager::impl::mark_study_pending(), and kcenon::pacs::client::prefetch_manager::impl::record_prefetch_history().

Here is the call graph for this function:

◆ process_worklist()

void kcenon::pacs::client::prefetch_manager::process_worklist ( const std::vector< core::dicom_dataset > & worklist_items)

Process worklist items and trigger prefetch.

Evaluates each worklist item against enabled rules and triggers appropriate prefetch operations.

Parameters
worklist_itemsWorklist items from MWL query
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 608 of file prefetch_manager.cpp.

609 {
610 for (const auto& item : worklist_items) {
611 // Extract relevant fields from worklist item
612 auto patient_id = get_dataset_value(item, core::tags::patient_id);
613 auto modality_val = get_dataset_value(item, core::tags::modality);
614 auto body_part = get_dataset_value(item, body_part_examined_tag);
615 auto station_ae = get_dataset_value(item, core::tags::scheduled_station_ae_title);
616
617 if (patient_id.empty()) {
618 continue;
619 }
620
621 // Find matching rules
622 auto rules = impl_->get_matching_rules(
624
625 for (const auto& rule : rules) {
626 // Trigger prefetch for this patient
627 auto result = prefetch_priors(patient_id, modality_val, body_part);
628
629 // Update rule statistics
630 impl_->increment_rule_stats(rule.rule_id, result.studies_prefetched);
631
632 impl_->logger->debug_fmt("Worklist prefetch for patient {}: {} studies prefetched",
633 patient_id, result.studies_prefetched);
634 }
635 }
636}
@ station_ae
(0008,1010) Station Name or calling AE
@ worklist_match
Triggered by worklist entry.
constexpr dicom_tag patient_id
Patient ID.
constexpr dicom_tag modality
Modality.
constexpr dicom_tag scheduled_station_ae_title
Scheduled Station AE Title.
void increment_rule_stats(const std::string &rule_id, size_t studies)

References kcenon::pacs::client::body_part, kcenon::pacs::client::prefetch_manager::impl::get_matching_rules(), impl_, kcenon::pacs::client::prefetch_manager::impl::increment_rule_stats(), kcenon::pacs::client::prefetch_manager::impl::logger, kcenon::pacs::core::tags::modality, kcenon::pacs::core::tags::patient_id, prefetch_priors(), kcenon::pacs::core::tags::scheduled_station_ae_title, kcenon::pacs::client::station_ae, and kcenon::pacs::client::worklist_match.

Referenced by process_worklist_async().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_worklist_async()

std::future< void > kcenon::pacs::client::prefetch_manager::process_worklist_async ( const std::vector< core::dicom_dataset > & worklist_items) -> std::future<void>
nodiscard

Process worklist items asynchronously.

Parameters
worklist_itemsWorklist items from MWL query
Returns
Future that completes when processing is done
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 638 of file prefetch_manager.cpp.

639 {
640 return std::async(std::launch::async, [this, worklist_items]() {
641 process_worklist(worklist_items);
642 });
643}
void process_worklist(const std::vector< core::dicom_dataset > &worklist_items)
Process worklist items and trigger prefetch.

References process_worklist().

Here is the call graph for this function:

◆ remove_rule()

kcenon::pacs::VoidResult kcenon::pacs::client::prefetch_manager::remove_rule ( std::string_view rule_id) -> kcenon::pacs::VoidResult
nodiscard

Remove a prefetch rule.

Parameters
rule_idID of the rule to remove
Returns
VoidResult indicating success or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 553 of file prefetch_manager.cpp.

553 {
554 // Remove from repository
555 #ifdef PACS_WITH_DATABASE_SYSTEM
556 if (impl_->repositories.rules) {
557 auto result = impl_->repositories.rules->remove(std::string(rule_id));
558 if (result.is_err()) {
559 return result;
560 }
561 } else if (impl_->compatibility_repo) {
562 auto result = impl_->compatibility_repo->remove_rule(rule_id);
563 if (result.is_err()) {
564 return result;
565 }
566 }
567 #else
569 auto result = impl_->compatibility_repo->remove_rule(rule_id);
570 if (result.is_err()) {
571 return result;
572 }
573 }
574 #endif
575
576 // Remove from cache
577 {
578 std::unique_lock lock(impl_->rules_mutex);
579 impl_->rules_cache.erase(
580 std::remove_if(impl_->rules_cache.begin(), impl_->rules_cache.end(),
581 [&rule_id](const prefetch_rule& r) { return r.rule_id == rule_id; }),
582 impl_->rules_cache.end());
583 }
584
585 impl_->logger->info_fmt("Removed prefetch rule: {}", std::string(rule_id));
586 return kcenon::common::ok();
587}

References kcenon::pacs::client::prefetch_manager::impl::compatibility_repo, impl_, kcenon::pacs::client::prefetch_manager::impl::logger, kcenon::pacs::client::prefetch_manager::impl::repositories, kcenon::pacs::client::prefetch_repositories::rules, kcenon::pacs::client::prefetch_manager::impl::rules_cache, and kcenon::pacs::client::prefetch_manager::impl::rules_mutex.

◆ set_config()

void kcenon::pacs::client::prefetch_manager::set_config ( prefetch_manager_config new_config)

Update configuration.

Parameters
new_configNew configuration to apply
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 912 of file prefetch_manager.cpp.

912 {
913 impl_->config = new_config;
914}

References kcenon::pacs::client::prefetch_manager::impl::config, and impl_.

◆ start_scheduler()

void kcenon::pacs::client::prefetch_manager::start_scheduler ( )

Start the scheduler for cron-based rules.

Begins checking and executing scheduled prefetch rules. Does nothing if already running.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 776 of file prefetch_manager.cpp.

776 {
777 if (impl_->scheduler_running.load()) {
778 return;
779 }
780
781 impl_->scheduler_running.store(true);
782 impl_->scheduler_thread = std::thread([this]() {
784 });
785
786 impl_->logger->info("Started prefetch scheduler");
787}

References impl_, kcenon::pacs::client::prefetch_manager::impl::logger, kcenon::pacs::client::prefetch_manager::impl::scheduler_loop(), kcenon::pacs::client::prefetch_manager::impl::scheduler_running, and kcenon::pacs::client::prefetch_manager::impl::scheduler_thread.

Here is the call graph for this function:

◆ start_worklist_monitor()

void kcenon::pacs::client::prefetch_manager::start_worklist_monitor ( std::string_view worklist_node_id)

Start the worklist monitor.

Begins periodic polling of the worklist for new items.

Parameters
worklist_node_idNode ID for worklist queries
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 817 of file prefetch_manager.cpp.

817 {
818 if (impl_->worklist_monitor_running.load()) {
819 return;
820 }
821
822 impl_->worklist_node_id = std::string(worklist_node_id);
823 impl_->worklist_monitor_running.store(true);
824 impl_->worklist_monitor_thread = std::thread([this]() {
826 });
827
828 impl_->logger->info_fmt("Started worklist monitor for node {}", std::string(worklist_node_id));
829}

References impl_, kcenon::pacs::client::prefetch_manager::impl::logger, kcenon::pacs::client::prefetch_manager::impl::worklist_monitor_loop(), kcenon::pacs::client::prefetch_manager::impl::worklist_monitor_running, kcenon::pacs::client::prefetch_manager::impl::worklist_monitor_thread, and kcenon::pacs::client::prefetch_manager::impl::worklist_node_id.

Here is the call graph for this function:

◆ stop_scheduler()

void kcenon::pacs::client::prefetch_manager::stop_scheduler ( )

Stop the scheduler.

Stops the scheduler thread. Does nothing if not running.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 789 of file prefetch_manager.cpp.

789 {
790 if (!impl_->scheduler_running.load()) {
791 return;
792 }
793
794 impl_->scheduler_running.store(false);
795
796 // Notify with lock held to ensure thread sees the flag change
797 {
798 std::lock_guard<std::mutex> lock(impl_->scheduler_mutex);
799 impl_->scheduler_cv.notify_all();
800 }
801
802 if (impl_->scheduler_thread.joinable()) {
803 impl_->scheduler_thread.join();
804 }
805
806 impl_->logger->info("Stopped prefetch scheduler");
807}

References impl_, kcenon::pacs::client::prefetch_manager::impl::logger, kcenon::pacs::client::prefetch_manager::impl::scheduler_cv, kcenon::pacs::client::prefetch_manager::impl::scheduler_mutex, kcenon::pacs::client::prefetch_manager::impl::scheduler_running, and kcenon::pacs::client::prefetch_manager::impl::scheduler_thread.

Referenced by ~prefetch_manager().

Here is the caller graph for this function:

◆ stop_worklist_monitor()

void kcenon::pacs::client::prefetch_manager::stop_worklist_monitor ( )

Stop the worklist monitor.

Stops periodic worklist polling. Does nothing if not running.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 831 of file prefetch_manager.cpp.

831 {
832 if (!impl_->worklist_monitor_running.load()) {
833 return;
834 }
835
836 impl_->worklist_monitor_running.store(false);
837
838 // Notify with lock held to ensure thread sees the flag change
839 {
840 std::lock_guard<std::mutex> lock(impl_->worklist_mutex);
841 impl_->worklist_cv.notify_all();
842 }
843
844 if (impl_->worklist_monitor_thread.joinable()) {
846 }
847
848 impl_->logger->info("Stopped worklist monitor");
849}

References impl_, kcenon::pacs::client::prefetch_manager::impl::logger, kcenon::pacs::client::prefetch_manager::impl::worklist_cv, kcenon::pacs::client::prefetch_manager::impl::worklist_monitor_running, kcenon::pacs::client::prefetch_manager::impl::worklist_monitor_thread, and kcenon::pacs::client::prefetch_manager::impl::worklist_mutex.

Referenced by ~prefetch_manager().

Here is the caller graph for this function:

◆ update_rule()

kcenon::pacs::VoidResult kcenon::pacs::client::prefetch_manager::update_rule ( const prefetch_rule & rule) -> kcenon::pacs::VoidResult
nodiscard

Update an existing prefetch rule.

Parameters
ruleThe rule to update (rule_id must match existing)
Returns
VoidResult indicating success or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/prefetch_manager.h.

Definition at line 511 of file prefetch_manager.cpp.

511 {
512 if (rule.rule_id.empty()) {
513 return kcenon::pacs::pacs_void_error(-1, "Rule ID is required for update");
514 }
515
516 // Save to repository
517 #ifdef PACS_WITH_DATABASE_SYSTEM
518 if (impl_->repositories.rules) {
519 auto result = impl_->repositories.rules->save(rule);
520 if (result.is_err()) {
521 return result.error();
522 }
523 } else if (impl_->compatibility_repo) {
524 auto result = impl_->compatibility_repo->save_rule(rule);
525 if (result.is_err()) {
526 return result;
527 }
528 }
529 #else
531 auto result = impl_->compatibility_repo->save_rule(rule);
532 if (result.is_err()) {
533 return result;
534 }
535 }
536 #endif
537
538 // Update cache
539 {
540 std::unique_lock lock(impl_->rules_mutex);
541 for (auto& cached_rule : impl_->rules_cache) {
542 if (cached_rule.rule_id == rule.rule_id) {
543 cached_rule = rule;
544 break;
545 }
546 }
547 }
548
549 impl_->logger->info_fmt("Updated prefetch rule: {}", rule.rule_id);
550 return kcenon::common::ok();
551}
VoidResult pacs_void_error(int code, const std::string &message, const std::string &details="")
Create a PACS void error result.
Definition result.h:249

References kcenon::pacs::client::prefetch_manager::impl::compatibility_repo, impl_, kcenon::pacs::client::prefetch_manager::impl::logger, kcenon::pacs::pacs_void_error(), kcenon::pacs::client::prefetch_manager::impl::repositories, kcenon::pacs::client::prefetch_rule::rule_id, kcenon::pacs::client::prefetch_repositories::rules, kcenon::pacs::client::prefetch_manager::impl::rules_cache, and kcenon::pacs::client::prefetch_manager::impl::rules_mutex.

Here is the call graph for this function:

Member Data Documentation

◆ impl_


The documentation for this class was generated from the following files: