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

#include <sync_manager.h>

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

Classes

struct  impl
 

Public Member Functions

 sync_manager (sync_repositories repositories, std::shared_ptr< remote_node_manager > node_manager, std::shared_ptr< job_manager > job_manager, std::shared_ptr< services::query_scu > query_scu, std::shared_ptr< di::ILogger > logger=nullptr)
 Construct a sync manager from split repositories.
 
 sync_manager (const sync_manager_config &config, sync_repositories repositories, std::shared_ptr< remote_node_manager > node_manager, std::shared_ptr< job_manager > job_manager, std::shared_ptr< services::query_scu > query_scu, std::shared_ptr< di::ILogger > logger=nullptr)
 Construct a sync manager from split repositories with custom configuration.
 
 sync_manager (std::shared_ptr< storage::sync_repository > repo, std::shared_ptr< remote_node_manager > node_manager, std::shared_ptr< job_manager > job_manager, std::shared_ptr< services::query_scu > query_scu, std::shared_ptr< di::ILogger > logger=nullptr)
 Construct a sync manager with default configuration.
 
 sync_manager (const sync_manager_config &config, std::shared_ptr< storage::sync_repository > repo, std::shared_ptr< remote_node_manager > node_manager, std::shared_ptr< job_manager > job_manager, std::shared_ptr< services::query_scu > query_scu, std::shared_ptr< di::ILogger > logger=nullptr)
 Construct a sync manager with custom configuration.
 
 ~sync_manager ()
 Destructor - stops scheduler if running.
 
 sync_manager (const sync_manager &)=delete
 
auto operator= (const sync_manager &) -> sync_manager &=delete
 
 sync_manager (sync_manager &&)=delete
 
auto operator= (sync_manager &&) -> sync_manager &=delete
 
auto add_config (const sync_config &config) -> kcenon::pacs::VoidResult
 Add a new sync configuration.
 
auto update_config (const sync_config &config) -> kcenon::pacs::VoidResult
 Update an existing sync configuration.
 
auto remove_config (std::string_view config_id) -> kcenon::pacs::VoidResult
 Remove a sync configuration.
 
auto get_config (std::string_view config_id) const -> std::optional< sync_config >
 Get a sync configuration by ID.
 
auto list_configs () const -> std::vector< sync_config >
 List all sync configurations.
 
auto sync_now (std::string_view config_id) -> std::string
 Start sync immediately for a configuration.
 
auto full_sync (std::string_view config_id) -> std::string
 Perform a full sync for a configuration.
 
auto incremental_sync (std::string_view config_id) -> std::string
 Perform an incremental sync for a configuration.
 
auto wait_for_sync (std::string_view job_id) -> std::future< sync_result >
 Wait for a sync operation to complete.
 
auto compare (std::string_view config_id) -> sync_result
 Compare local and remote data without syncing.
 
auto compare_async (std::string_view config_id) -> std::future< sync_result >
 Compare local and remote data asynchronously.
 
auto get_conflicts () const -> std::vector< sync_conflict >
 Get all unresolved conflicts.
 
auto get_conflicts (std::string_view config_id) const -> std::vector< sync_conflict >
 Get unresolved conflicts for a specific configuration.
 
auto resolve_conflict (std::string_view study_uid, conflict_resolution resolution) -> kcenon::pacs::VoidResult
 Resolve a specific conflict.
 
auto resolve_all_conflicts (std::string_view config_id, conflict_resolution resolution) -> kcenon::pacs::VoidResult
 Resolve all conflicts for a configuration.
 
void start_scheduler ()
 Start the sync scheduler.
 
void stop_scheduler ()
 Stop the sync scheduler.
 
auto is_scheduler_running () const noexcept -> bool
 Check if scheduler is running.
 
auto is_syncing (std::string_view config_id) const -> bool
 Check if a sync is currently running for a configuration.
 
auto get_last_result (std::string_view config_id) const -> sync_result
 Get the last sync result for a configuration.
 
auto get_statistics () const -> sync_statistics
 Get overall sync statistics.
 
auto get_statistics (std::string_view config_id) const -> sync_statistics
 Get statistics for a specific configuration.
 
void set_progress_callback (sync_progress_callback callback)
 Set callback for sync progress updates.
 
void set_completion_callback (sync_completion_callback callback)
 Set callback for sync completion.
 
void set_conflict_callback (sync_conflict_callback callback)
 Set callback for conflict detection.
 
auto config () const noexcept -> const sync_manager_config &
 Get current manager configuration.
 

Private Attributes

std::unique_ptr< implimpl_
 

Detailed Description

Definition at line 102 of file sync_manager.h.

Constructor & Destructor Documentation

◆ sync_manager() [1/6]

kcenon::pacs::client::sync_manager::sync_manager ( sync_repositories repositories,
std::shared_ptr< remote_node_manager > node_manager,
std::shared_ptr< job_manager > job_manager,
std::shared_ptr< services::query_scu > query_scu,
std::shared_ptr< di::ILogger > logger = nullptr )
explicit

Construct a sync manager from split repositories.

Parameters
repositoriesSplit sync repositories for configs, conflicts, and history
node_managerRemote node manager (required)
job_managerJob manager for async operations (required)
query_scuQuery SCU for study comparisons (required)
loggerLogger instance (optional)
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 733 of file sync_manager.cpp.

739 : sync_manager(sync_manager_config{}, std::move(repositories),
740 std::move(node_manager), std::move(job_manager),
741 std::move(query_scu), std::move(logger)) {}
sync_manager(sync_repositories repositories, std::shared_ptr< remote_node_manager > node_manager, std::shared_ptr< job_manager > job_manager, std::shared_ptr< services::query_scu > query_scu, std::shared_ptr< di::ILogger > logger=nullptr)
Construct a sync manager from split repositories.

◆ sync_manager() [2/6]

kcenon::pacs::client::sync_manager::sync_manager ( const sync_manager_config & config,
sync_repositories repositories,
std::shared_ptr< remote_node_manager > node_manager,
std::shared_ptr< job_manager > job_manager,
std::shared_ptr< services::query_scu > query_scu,
std::shared_ptr< di::ILogger > logger = nullptr )
explicit

Construct a sync manager from split repositories with custom configuration.

Parameters
configManager configuration
repositoriesSplit sync repositories for configs, conflicts, and history
node_managerRemote node manager (required)
job_managerJob manager for async operations (required)
query_scuQuery SCU for study comparisons (required)
loggerLogger instance (optional)

Definition at line 743 of file sync_manager.cpp.

750 : impl_(std::make_unique<impl>()) {
751
753 impl_->repositories = std::move(repositories);
754 impl_->node_manager = std::move(node_manager);
755 impl_->job_mgr = std::move(job_manager);
756 impl_->query_scu = std::move(query_scu);
757 impl_->logger = logger ? std::move(logger) : di::null_logger();
758
761}
auto config() const noexcept -> const sync_manager_config &
Get current manager configuration.
std::unique_ptr< impl > impl_
std::shared_ptr< job_manager > job_mgr
std::shared_ptr< di::ILogger > logger
std::shared_ptr< services::query_scu > query_scu
std::shared_ptr< remote_node_manager > node_manager

References config(), kcenon::pacs::client::sync_manager::impl::config, impl_, kcenon::pacs::client::sync_manager::impl::job_mgr, kcenon::pacs::client::sync_manager::impl::load_configs_from_repo(), kcenon::pacs::client::sync_manager::impl::load_conflicts_from_repo(), kcenon::pacs::client::sync_manager::impl::logger, kcenon::pacs::client::sync_manager::impl::node_manager, kcenon::pacs::di::null_logger(), kcenon::pacs::client::sync_manager::impl::query_scu, and kcenon::pacs::client::sync_manager::impl::repositories.

Here is the call graph for this function:

◆ sync_manager() [3/6]

kcenon::pacs::client::sync_manager::sync_manager ( std::shared_ptr< storage::sync_repository > repo,
std::shared_ptr< remote_node_manager > node_manager,
std::shared_ptr< job_manager > job_manager,
std::shared_ptr< services::query_scu > query_scu,
std::shared_ptr< di::ILogger > logger = nullptr )
explicit

Construct a sync manager with default configuration.

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

Parameters
repoSync repository for persistence (required)
node_managerRemote node manager (required)
job_managerJob manager for async operations (required)
query_scuQuery SCU for study comparisons (required)
loggerLogger instance (optional)

Definition at line 763 of file sync_manager.cpp.

769 : sync_manager(sync_manager_config{}, std::move(repo), std::move(node_manager),
770 std::move(job_manager), std::move(query_scu), std::move(logger)) {
771}

◆ sync_manager() [4/6]

kcenon::pacs::client::sync_manager::sync_manager ( const sync_manager_config & config,
std::shared_ptr< storage::sync_repository > repo,
std::shared_ptr< remote_node_manager > node_manager,
std::shared_ptr< job_manager > job_manager,
std::shared_ptr< services::query_scu > query_scu,
std::shared_ptr< di::ILogger > logger = nullptr )
explicit

Construct a sync manager with custom configuration.

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

Parameters
configManager configuration
repoSync repository for persistence (required)
node_managerRemote node manager (required)
job_managerJob manager for async operations (required)
query_scuQuery SCU for study comparisons (required)
loggerLogger instance (optional)

Definition at line 773 of file sync_manager.cpp.

780 : impl_(std::make_unique<impl>()) {
781
783 impl_->compatibility_repo = std::move(repo);
784 impl_->node_manager = std::move(node_manager);
785 impl_->job_mgr = std::move(job_manager);
786 impl_->query_scu = std::move(query_scu);
787 impl_->logger = logger ? std::move(logger) : di::null_logger();
788
791}
std::shared_ptr< storage::sync_repository > compatibility_repo

References kcenon::pacs::client::sync_manager::impl::compatibility_repo, config(), kcenon::pacs::client::sync_manager::impl::config, impl_, kcenon::pacs::client::sync_manager::impl::job_mgr, kcenon::pacs::client::sync_manager::impl::load_configs_from_repo(), kcenon::pacs::client::sync_manager::impl::load_conflicts_from_repo(), kcenon::pacs::client::sync_manager::impl::logger, kcenon::pacs::client::sync_manager::impl::node_manager, kcenon::pacs::di::null_logger(), and kcenon::pacs::client::sync_manager::impl::query_scu.

Here is the call graph for this function:

◆ ~sync_manager()

kcenon::pacs::client::sync_manager::~sync_manager ( )

Destructor - stops scheduler if running.

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

Definition at line 793 of file sync_manager.cpp.

793 {
795}
void stop_scheduler()
Stop the sync scheduler.

References stop_scheduler().

Here is the call graph for this function:

◆ sync_manager() [5/6]

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

◆ sync_manager() [6/6]

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

Member Function Documentation

◆ add_config()

kcenon::pacs::VoidResult kcenon::pacs::client::sync_manager::add_config ( const sync_config & config) -> kcenon::pacs::VoidResult
nodiscard

Add a new sync configuration.

Parameters
configThe configuration to add
Returns
VoidResult indicating success or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 801 of file sync_manager.cpp.

801 {
802 if (config.config_id.empty()) {
804 kcenon::pacs::error_codes::invalid_argument,
805 "Config ID cannot be empty");
806 }
807
808 if (config.source_node_id.empty()) {
810 kcenon::pacs::error_codes::invalid_argument,
811 "Source node ID cannot be empty");
812 }
813
814 // Check for duplicate
815 if (impl_->get_config_from_cache(config.config_id).has_value()) {
817 kcenon::pacs::error_codes::already_exists,
818 "Config already exists: " + config.config_id);
819 }
820
822
823 if (impl_->logger) {
824 impl_->logger->info_fmt("Added sync config '{}' for node '{}'",
825 config.config_id, config.source_node_id);
826 }
827
828 return kcenon::pacs::ok();
829}
VoidResult pacs_void_error(int code, const std::string &message, const std::string &details="")
Create a PACS void error result.
Definition result.h:249
void save_config(const sync_config &cfg)
std::optional< sync_config > get_config_from_cache(std::string_view config_id) const

References config(), kcenon::pacs::client::sync_manager::impl::get_config_from_cache(), impl_, kcenon::pacs::client::sync_manager::impl::logger, kcenon::pacs::pacs_void_error(), and kcenon::pacs::client::sync_manager::impl::save_config().

Here is the call graph for this function:

◆ compare()

sync_result kcenon::pacs::client::sync_manager::compare ( std::string_view config_id) -> sync_result
nodiscard

Compare local and remote data without syncing.

Returns a sync_result showing what would be synced.

Parameters
config_idThe configuration ID to compare
Returns
Sync result with comparison data
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 959 of file sync_manager.cpp.

959 {
960 sync_result result;
961 result.config_id = std::string(config_id);
962 result.started_at = std::chrono::system_clock::now();
963
964 auto config_opt = impl_->get_config_from_cache(config_id);
965 if (!config_opt) {
966 result.errors.push_back("Config not found: " + std::string(config_id));
967 result.completed_at = std::chrono::system_clock::now();
968 return result;
969 }
970
971 const auto& cfg = *config_opt;
972
973 // Query remote studies
974 auto sync_start_time = std::chrono::system_clock::now() - cfg.lookback;
975 auto remote_studies = impl_->query_remote_studies(cfg, sync_start_time, result);
976
977 if (!result.errors.empty()) {
978 result.completed_at = std::chrono::system_clock::now();
979 return result;
980 }
981
982 result.studies_checked = remote_studies.size();
983
984 // Compare with local
985 auto conflicts = impl_->compare_with_local(cfg, remote_studies, result);
986 result.conflicts = conflicts;
987
988 result.success = true;
989 result.completed_at = std::chrono::system_clock::now();
990 result.elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
991 result.completed_at - result.started_at);
992
993 return result;
994}
std::vector< sync_conflict > compare_with_local(const sync_config &cfg, const std::vector< std::string > &remote_study_uids, sync_result &result)
std::vector< std::string > query_remote_studies(const sync_config &cfg, std::chrono::system_clock::time_point since, sync_result &result)

References kcenon::pacs::client::sync_manager::impl::compare_with_local(), kcenon::pacs::client::sync_result::completed_at, kcenon::pacs::client::sync_result::config_id, kcenon::pacs::client::sync_result::conflicts, kcenon::pacs::client::sync_result::elapsed, kcenon::pacs::client::sync_result::errors, kcenon::pacs::client::sync_manager::impl::get_config_from_cache(), impl_, kcenon::pacs::client::sync_manager::impl::query_remote_studies(), kcenon::pacs::client::sync_result::started_at, kcenon::pacs::client::sync_result::studies_checked, and kcenon::pacs::client::sync_result::success.

Referenced by compare_async().

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

◆ compare_async()

std::future< sync_result > kcenon::pacs::client::sync_manager::compare_async ( std::string_view config_id) -> std::future<sync_result>
nodiscard

Compare local and remote data asynchronously.

Parameters
config_idThe configuration ID to compare
Returns
Future containing the comparison result
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 996 of file sync_manager.cpp.

996 {
997 return std::async(std::launch::async, [this, id = std::string(config_id)]() {
998 return compare(id);
999 });
1000}
auto compare(std::string_view config_id) -> sync_result
Compare local and remote data without syncing.

References compare().

Here is the call graph for this function:

◆ config()

const sync_manager_config & kcenon::pacs::client::sync_manager::config ( ) const -> const sync_manager_config&
nodiscardnoexcept

Get current manager configuration.

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

Definition at line 1225 of file sync_manager.cpp.

1225 {
1226 return impl_->config;
1227}

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

Referenced by add_config(), sync_manager(), sync_manager(), and update_config().

Here is the caller graph for this function:

◆ full_sync()

std::string kcenon::pacs::client::sync_manager::full_sync ( std::string_view config_id) -> std::string
nodiscard

Perform a full sync for a configuration.

Syncs all data within the lookback period, ignoring last sync time.

Parameters
config_idThe configuration ID to sync
Returns
Job ID for tracking progress
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 915 of file sync_manager.cpp.

915 {
916 auto config_opt = impl_->get_config_from_cache(config_id);
917 if (!config_opt) {
918 return "";
919 }
920
921 impl_->mark_sync_active(config_id);
922 auto result = impl_->perform_sync(*config_opt, true);
923 impl_->mark_sync_inactive(config_id);
924 impl_->notify_completion(std::string(config_id), result);
925
926 return result.job_id;
927}
sync_result perform_sync(const sync_config &cfg, bool full_sync)
void mark_sync_inactive(std::string_view config_id)
void mark_sync_active(std::string_view config_id)
void notify_completion(const std::string &config_id, const sync_result &result)

References kcenon::pacs::client::sync_manager::impl::get_config_from_cache(), impl_, kcenon::pacs::client::sync_manager::impl::mark_sync_active(), kcenon::pacs::client::sync_manager::impl::mark_sync_inactive(), kcenon::pacs::client::sync_manager::impl::notify_completion(), and kcenon::pacs::client::sync_manager::impl::perform_sync().

Referenced by kcenon::pacs::client::sync_manager::impl::perform_sync().

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

◆ get_config()

std::optional< sync_config > kcenon::pacs::client::sync_manager::get_config ( std::string_view config_id) const -> std::optional<sync_config>
nodiscard

Get a sync configuration by ID.

Parameters
config_idThe configuration ID to retrieve
Returns
Optional containing the config if found
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 884 of file sync_manager.cpp.

884 {
885 return impl_->get_config_from_cache(config_id);
886}

References kcenon::pacs::client::sync_manager::impl::get_config_from_cache(), and impl_.

Here is the call graph for this function:

◆ get_conflicts() [1/2]

std::vector< sync_conflict > kcenon::pacs::client::sync_manager::get_conflicts ( ) const -> std::vector<sync_conflict>
nodiscard

Get all unresolved conflicts.

Returns
Vector of all unresolved conflicts
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 1006 of file sync_manager.cpp.

1006 {
1007 std::lock_guard lock(impl_->conflicts_mutex);
1008 std::vector<sync_conflict> unresolved;
1009 std::copy_if(impl_->conflicts.begin(), impl_->conflicts.end(),
1010 std::back_inserter(unresolved),
1011 [](const sync_conflict& c) { return !c.resolved; });
1012 return unresolved;
1013}
std::vector< sync_conflict > conflicts

References kcenon::pacs::client::sync_manager::impl::conflicts, kcenon::pacs::client::sync_manager::impl::conflicts_mutex, and impl_.

◆ get_conflicts() [2/2]

std::vector< sync_conflict > kcenon::pacs::client::sync_manager::get_conflicts ( std::string_view config_id) const -> std::vector<sync_conflict>
nodiscard

Get unresolved conflicts for a specific configuration.

Parameters
config_idThe configuration ID
Returns
Vector of unresolved conflicts for that config

Definition at line 1015 of file sync_manager.cpp.

1015 {
1016 std::lock_guard lock(impl_->conflicts_mutex);
1017 std::vector<sync_conflict> filtered;
1018 std::copy_if(impl_->conflicts.begin(), impl_->conflicts.end(),
1019 std::back_inserter(filtered),
1020 [&config_id](const sync_conflict& c) {
1021 return !c.resolved && c.config_id == config_id;
1022 });
1023 return filtered;
1024}

References kcenon::pacs::client::sync_manager::impl::conflicts, kcenon::pacs::client::sync_manager::impl::conflicts_mutex, and impl_.

◆ get_last_result()

sync_result kcenon::pacs::client::sync_manager::get_last_result ( std::string_view config_id) const -> sync_result
nodiscard

Get the last sync result for a configuration.

Parameters
config_idThe configuration ID
Returns
Last sync result
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 1152 of file sync_manager.cpp.

1152 {
1153 std::shared_lock lock(impl_->results_mutex);
1154 auto it = impl_->last_results.find(std::string(config_id));
1155 if (it != impl_->last_results.end()) {
1156 return it->second;
1157 }
1158 return sync_result{};
1159}
std::unordered_map< std::string, sync_result > last_results

References impl_, kcenon::pacs::client::sync_manager::impl::last_results, and kcenon::pacs::client::sync_manager::impl::results_mutex.

◆ get_statistics() [1/2]

sync_statistics kcenon::pacs::client::sync_manager::get_statistics ( ) const -> sync_statistics
nodiscard

Get overall sync statistics.

Returns
Aggregate statistics for all sync operations
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 1165 of file sync_manager.cpp.

1165 {
1166 sync_statistics stats;
1167 stats.total_syncs = impl_->total_syncs.load(std::memory_order_relaxed);
1168 stats.successful_syncs = impl_->successful_syncs.load(std::memory_order_relaxed);
1169 stats.failed_syncs = impl_->failed_syncs.load(std::memory_order_relaxed);
1170 stats.total_studies_synced = impl_->total_studies_synced.load(std::memory_order_relaxed);
1171 stats.total_bytes_transferred = impl_->total_bytes_transferred.load(std::memory_order_relaxed);
1172 stats.total_conflicts_detected = impl_->total_conflicts_detected.load(std::memory_order_relaxed);
1173 stats.total_conflicts_resolved = impl_->total_conflicts_resolved.load(std::memory_order_relaxed);
1174 return stats;
1175}

References kcenon::pacs::client::sync_manager::impl::failed_syncs, impl_, kcenon::pacs::client::sync_manager::impl::successful_syncs, kcenon::pacs::client::sync_manager::impl::total_bytes_transferred, kcenon::pacs::client::sync_manager::impl::total_conflicts_detected, kcenon::pacs::client::sync_manager::impl::total_conflicts_resolved, kcenon::pacs::client::sync_manager::impl::total_studies_synced, and kcenon::pacs::client::sync_manager::impl::total_syncs.

◆ get_statistics() [2/2]

sync_statistics kcenon::pacs::client::sync_manager::get_statistics ( std::string_view config_id) const -> sync_statistics
nodiscard

Get statistics for a specific configuration.

Parameters
config_idThe configuration ID
Returns
Statistics for that configuration

Definition at line 1177 of file sync_manager.cpp.

1177 {
1178 sync_statistics stats;
1179
1180 auto config_opt = impl_->get_config_from_cache(config_id);
1181 if (config_opt) {
1182 stats.total_syncs = config_opt->total_syncs;
1183 stats.total_studies_synced = config_opt->studies_synced;
1184 }
1185
1186 // Count conflicts for this config
1187 {
1188 std::lock_guard lock(impl_->conflicts_mutex);
1189 for (const auto& c : impl_->conflicts) {
1190 if (c.config_id == config_id) {
1191 stats.total_conflicts_detected++;
1192 if (c.resolved) {
1193 stats.total_conflicts_resolved++;
1194 }
1195 }
1196 }
1197 }
1198
1199 return stats;
1200}

References kcenon::pacs::client::sync_manager::impl::conflicts, kcenon::pacs::client::sync_manager::impl::conflicts_mutex, kcenon::pacs::client::sync_manager::impl::get_config_from_cache(), and impl_.

Here is the call graph for this function:

◆ incremental_sync()

std::string kcenon::pacs::client::sync_manager::incremental_sync ( std::string_view config_id) -> std::string
nodiscard

Perform an incremental sync for a configuration.

Only syncs data modified since the last successful sync.

Parameters
config_idThe configuration ID to sync
Returns
Job ID for tracking progress
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 929 of file sync_manager.cpp.

929 {
930 auto config_opt = impl_->get_config_from_cache(config_id);
931 if (!config_opt) {
932 return "";
933 }
934
935 impl_->mark_sync_active(config_id);
936 auto result = impl_->perform_sync(*config_opt, false);
937 impl_->mark_sync_inactive(config_id);
938 impl_->notify_completion(std::string(config_id), result);
939
940 return result.job_id;
941}

References kcenon::pacs::client::sync_manager::impl::get_config_from_cache(), impl_, kcenon::pacs::client::sync_manager::impl::mark_sync_active(), kcenon::pacs::client::sync_manager::impl::mark_sync_inactive(), kcenon::pacs::client::sync_manager::impl::notify_completion(), and kcenon::pacs::client::sync_manager::impl::perform_sync().

Here is the call graph for this function:

◆ is_scheduler_running()

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

Check if scheduler is running.

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

Definition at line 1140 of file sync_manager.cpp.

1140 {
1141 return impl_->scheduler_running.load();
1142}

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

◆ is_syncing()

bool kcenon::pacs::client::sync_manager::is_syncing ( std::string_view config_id) const -> bool
nodiscard

Check if a sync is currently running for a configuration.

Parameters
config_idThe configuration ID to check
Returns
true if sync is in progress
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 1148 of file sync_manager.cpp.

1148 {
1149 return impl_->is_sync_active(config_id);
1150}
bool is_sync_active(std::string_view config_id) const

References impl_, and kcenon::pacs::client::sync_manager::impl::is_sync_active().

Here is the call graph for this function:

◆ list_configs()

std::vector< sync_config > kcenon::pacs::client::sync_manager::list_configs ( ) const -> std::vector<sync_config>
nodiscard

List all sync configurations.

Returns
Vector of all configurations
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 888 of file sync_manager.cpp.

888 {
889 std::shared_lock lock(impl_->configs_mutex);
890 return impl_->configs;
891}

References kcenon::pacs::client::sync_manager::impl::configs, kcenon::pacs::client::sync_manager::impl::configs_mutex, and impl_.

◆ operator=() [1/2]

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

◆ operator=() [2/2]

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

◆ remove_config()

kcenon::pacs::VoidResult kcenon::pacs::client::sync_manager::remove_config ( std::string_view config_id) -> kcenon::pacs::VoidResult
nodiscard

Remove a sync configuration.

Parameters
config_idThe ID of the configuration to remove
Returns
VoidResult indicating success or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 847 of file sync_manager.cpp.

847 {
848 {
849 std::unique_lock lock(impl_->configs_mutex);
850 auto it = std::find_if(impl_->configs.begin(), impl_->configs.end(),
851 [&config_id](const sync_config& c) {
852 return c.config_id == config_id;
853 });
854 if (it == impl_->configs.end()) {
856 kcenon::pacs::error_codes::not_found,
857 "Config not found: " + std::string(config_id));
858 }
859 impl_->configs.erase(it);
860 }
861
862 #ifdef PACS_WITH_DATABASE_SYSTEM
864 [[maybe_unused]] auto result =
865 impl_->repositories.configs->remove(std::string(config_id));
866 } else if (impl_->compatibility_repo) {
867 [[maybe_unused]] auto result =
868 impl_->compatibility_repo->remove_config(config_id);
869 }
870 #else
872 [[maybe_unused]] auto result =
873 impl_->compatibility_repo->remove_config(config_id);
874 }
875 #endif
876
877 if (impl_->logger) {
878 impl_->logger->info_fmt("Removed sync config '{}'", config_id);
879 }
880
881 return kcenon::pacs::ok();
882}
std::shared_ptr< storage::sync_config_repository > configs

References kcenon::pacs::client::sync_manager::impl::compatibility_repo, kcenon::pacs::client::sync_manager::impl::configs, kcenon::pacs::client::sync_repositories::configs, kcenon::pacs::client::sync_manager::impl::configs_mutex, impl_, kcenon::pacs::client::sync_manager::impl::logger, kcenon::pacs::pacs_void_error(), and kcenon::pacs::client::sync_manager::impl::repositories.

Here is the call graph for this function:

◆ resolve_all_conflicts()

kcenon::pacs::VoidResult kcenon::pacs::client::sync_manager::resolve_all_conflicts ( std::string_view config_id,
conflict_resolution resolution ) -> kcenon::pacs::VoidResult
nodiscard

Resolve all conflicts for a configuration.

Parameters
config_idThe configuration ID
resolutionHow to resolve all conflicts
Returns
VoidResult indicating success or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 1074 of file sync_manager.cpp.

1076 {
1077
1078 std::vector<std::string> study_uids;
1079
1080 {
1081 std::lock_guard lock(impl_->conflicts_mutex);
1082 for (const auto& c : impl_->conflicts) {
1083 if (c.config_id == config_id && !c.resolved) {
1084 study_uids.push_back(c.study_uid);
1085 }
1086 }
1087 }
1088
1089 for (const auto& uid : study_uids) {
1090 auto result = resolve_conflict(uid, resolution);
1091 if (result.is_err()) {
1092 return result;
1093 }
1094 }
1095
1096 if (impl_->logger) {
1097 impl_->logger->info_fmt("Resolved {} conflicts for config '{}'",
1098 study_uids.size(), config_id);
1099 }
1100
1101 return kcenon::pacs::ok();
1102}
auto resolve_conflict(std::string_view study_uid, conflict_resolution resolution) -> kcenon::pacs::VoidResult
Resolve a specific conflict.
std::string_view uid

References kcenon::pacs::client::sync_manager::impl::conflicts, kcenon::pacs::client::sync_manager::impl::conflicts_mutex, impl_, kcenon::pacs::client::sync_manager::impl::logger, resolve_conflict(), and uid.

Here is the call graph for this function:

◆ resolve_conflict()

kcenon::pacs::VoidResult kcenon::pacs::client::sync_manager::resolve_conflict ( std::string_view study_uid,
conflict_resolution resolution ) -> kcenon::pacs::VoidResult
nodiscard

Resolve a specific conflict.

Parameters
study_uidThe Study Instance UID of the conflict
resolutionHow to resolve the conflict
Returns
VoidResult indicating success or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 1026 of file sync_manager.cpp.

1028 {
1029
1030 std::lock_guard lock(impl_->conflicts_mutex);
1031
1032 auto it = std::find_if(impl_->conflicts.begin(), impl_->conflicts.end(),
1033 [&study_uid](const sync_conflict& c) {
1034 return c.study_uid == study_uid && !c.resolved;
1035 });
1036
1037 if (it == impl_->conflicts.end()) {
1039 kcenon::pacs::error_codes::not_found,
1040 "Conflict not found: " + std::string(study_uid));
1041 }
1042
1043 // Apply resolution
1044 sync_result dummy_result;
1045 impl_->resolve_conflict_internal(*it, resolution, dummy_result);
1046
1047 it->resolved = true;
1048 it->resolution_used = resolution;
1049 it->resolved_at = std::chrono::system_clock::now();
1050
1051 #ifdef PACS_WITH_DATABASE_SYSTEM
1053 [[maybe_unused]] auto result =
1054 impl_->repositories.conflicts->resolve(study_uid, resolution);
1055 } else if (impl_->compatibility_repo) {
1056 [[maybe_unused]] auto result =
1057 impl_->compatibility_repo->resolve_conflict(study_uid, resolution);
1058 }
1059 #else
1061 [[maybe_unused]] auto result =
1062 impl_->compatibility_repo->resolve_conflict(study_uid, resolution);
1063 }
1064 #endif
1065
1066 if (impl_->logger) {
1067 impl_->logger->info_fmt("Resolved conflict for study '{}' using {}",
1068 study_uid, to_string(resolution));
1069 }
1070
1071 return kcenon::pacs::ok();
1072}
constexpr const char * to_string(job_type type) noexcept
Convert job_type to string representation.
Definition job_types.h:54
void resolve_conflict_internal(const sync_conflict &conflict, conflict_resolution resolution, sync_result &result)
std::shared_ptr< storage::sync_conflict_repository > conflicts

References kcenon::pacs::client::sync_manager::impl::compatibility_repo, kcenon::pacs::client::sync_manager::impl::conflicts, kcenon::pacs::client::sync_repositories::conflicts, kcenon::pacs::client::sync_manager::impl::conflicts_mutex, impl_, kcenon::pacs::client::sync_manager::impl::logger, kcenon::pacs::pacs_void_error(), kcenon::pacs::client::sync_manager::impl::repositories, kcenon::pacs::client::sync_manager::impl::resolve_conflict_internal(), and kcenon::pacs::client::to_string().

Referenced by resolve_all_conflicts().

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

◆ set_completion_callback()

void kcenon::pacs::client::sync_manager::set_completion_callback ( sync_completion_callback callback)

Set callback for sync completion.

Parameters
callbackThe callback function
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 1211 of file sync_manager.cpp.

1211 {
1212 std::unique_lock lock(impl_->callbacks_mutex);
1213 impl_->completion_callback = std::move(callback);
1214}
sync_completion_callback completion_callback

References kcenon::pacs::client::sync_manager::impl::callbacks_mutex, kcenon::pacs::client::sync_manager::impl::completion_callback, and impl_.

◆ set_conflict_callback()

void kcenon::pacs::client::sync_manager::set_conflict_callback ( sync_conflict_callback callback)

Set callback for conflict detection.

Parameters
callbackThe callback function
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 1216 of file sync_manager.cpp.

1216 {
1217 std::unique_lock lock(impl_->callbacks_mutex);
1218 impl_->conflict_callback = std::move(callback);
1219}

References kcenon::pacs::client::sync_manager::impl::callbacks_mutex, kcenon::pacs::client::sync_manager::impl::conflict_callback, and impl_.

◆ set_progress_callback()

void kcenon::pacs::client::sync_manager::set_progress_callback ( sync_progress_callback callback)

Set callback for sync progress updates.

Parameters
callbackThe callback function
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 1206 of file sync_manager.cpp.

1206 {
1207 std::unique_lock lock(impl_->callbacks_mutex);
1208 impl_->progress_callback = std::move(callback);
1209}

References kcenon::pacs::client::sync_manager::impl::callbacks_mutex, impl_, and kcenon::pacs::client::sync_manager::impl::progress_callback.

◆ start_scheduler()

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

Start the sync scheduler.

Schedules syncs based on each config's schedule_cron setting.

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

Definition at line 1108 of file sync_manager.cpp.

1108 {
1109 if (impl_->scheduler_running.load()) {
1110 return;
1111 }
1112
1113 impl_->scheduler_running.store(true);
1114 impl_->scheduler_thread = std::thread([this]() {
1116 });
1117
1118 if (impl_->logger) {
1119 impl_->logger->info("Sync scheduler started");
1120 }
1121}

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

Here is the call graph for this function:

◆ stop_scheduler()

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

Stop the sync scheduler.

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

Definition at line 1123 of file sync_manager.cpp.

1123 {
1124 if (!impl_->scheduler_running.load()) {
1125 return;
1126 }
1127
1128 impl_->scheduler_running.store(false);
1129 impl_->scheduler_cv.notify_all();
1130
1131 if (impl_->scheduler_thread.joinable()) {
1132 impl_->scheduler_thread.join();
1133 }
1134
1135 if (impl_->logger) {
1136 impl_->logger->info("Sync scheduler stopped");
1137 }
1138}

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

Referenced by ~sync_manager().

Here is the caller graph for this function:

◆ sync_now()

std::string kcenon::pacs::client::sync_manager::sync_now ( std::string_view config_id) -> std::string
nodiscard

Start sync immediately for a configuration.

Uses the config's existing settings (incremental or full based on last_sync).

Parameters
config_idThe configuration ID to sync
Returns
Job ID for tracking progress
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 897 of file sync_manager.cpp.

897 {
898 auto config_opt = impl_->get_config_from_cache(config_id);
899 if (!config_opt) {
900 return "";
901 }
902
903 impl_->mark_sync_active(config_id);
904
905 // Determine if incremental or full based on last_successful_sync
906 bool full = config_opt->last_successful_sync == std::chrono::system_clock::time_point{};
907 auto result = impl_->perform_sync(*config_opt, full);
908
909 impl_->mark_sync_inactive(config_id);
910 impl_->notify_completion(std::string(config_id), result);
911
912 return result.job_id;
913}

References kcenon::pacs::client::sync_manager::impl::get_config_from_cache(), impl_, kcenon::pacs::client::sync_manager::impl::mark_sync_active(), kcenon::pacs::client::sync_manager::impl::mark_sync_inactive(), kcenon::pacs::client::sync_manager::impl::notify_completion(), and kcenon::pacs::client::sync_manager::impl::perform_sync().

Here is the call graph for this function:

◆ update_config()

kcenon::pacs::VoidResult kcenon::pacs::client::sync_manager::update_config ( const sync_config & config) -> kcenon::pacs::VoidResult
nodiscard

Update an existing sync configuration.

Parameters
configThe configuration to update (identified by config_id)
Returns
VoidResult indicating success or error
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 831 of file sync_manager.cpp.

831 {
832 if (!impl_->get_config_from_cache(config.config_id).has_value()) {
834 kcenon::pacs::error_codes::not_found,
835 "Config not found: " + config.config_id);
836 }
837
839
840 if (impl_->logger) {
841 impl_->logger->info_fmt("Updated sync config '{}'", config.config_id);
842 }
843
844 return kcenon::pacs::ok();
845}

References config(), kcenon::pacs::client::sync_manager::impl::get_config_from_cache(), impl_, kcenon::pacs::client::sync_manager::impl::logger, kcenon::pacs::pacs_void_error(), and kcenon::pacs::client::sync_manager::impl::save_config().

Here is the call graph for this function:

◆ wait_for_sync()

std::future< sync_result > kcenon::pacs::client::sync_manager::wait_for_sync ( std::string_view job_id) -> std::future<sync_result>
nodiscard

Wait for a sync operation to complete.

Parameters
job_idThe job ID returned from sync operations
Returns
Future containing the sync result
Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/client/sync_manager.h.

Definition at line 943 of file sync_manager.cpp.

943 {
944 auto promise = std::make_shared<std::promise<sync_result>>();
945 auto future = promise->get_future();
946
947 {
948 std::lock_guard lock(impl_->promises_mutex);
949 impl_->completion_promises[std::string(job_id)] = promise;
950 }
951
952 return future;
953}
std::unordered_map< std::string, std::shared_ptr< std::promise< sync_result > > > completion_promises

References kcenon::pacs::client::sync_manager::impl::completion_promises, impl_, and kcenon::pacs::client::sync_manager::impl::promises_mutex.

Member Data Documentation

◆ impl_


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