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

Background migration service for HSM. More...

#include <hsm_migration_service.h>

Collaboration diagram for kcenon::pacs::storage::hsm_migration_service:
Collaboration graph

Public Member Functions

 hsm_migration_service (hsm_storage &storage, const migration_service_config &config={})
 Construct migration service.
 
 hsm_migration_service (hsm_storage &storage, std::shared_ptr< kcenon::thread::thread_pool > thread_pool, const migration_service_config &config={})
 Construct migration service with thread pool.
 
 ~hsm_migration_service ()
 Destructor - ensures graceful shutdown.
 
 hsm_migration_service (const hsm_migration_service &)=delete
 Non-copyable.
 
hsm_migration_service & operator= (const hsm_migration_service &)=delete
 
 hsm_migration_service (hsm_migration_service &&)=delete
 Non-movable.
 
hsm_migration_service & operator= (hsm_migration_service &&)=delete
 
void start ()
 Start the background migration service.
 
void stop (bool wait_for_completion=true)
 Stop the background migration service.
 
auto is_running () const noexcept -> bool
 Check if the service is running.
 
auto run_migration_cycle () -> migration_result
 Manually trigger a migration cycle.
 
void trigger_cycle ()
 Trigger next cycle immediately.
 
auto get_last_result () const -> std::optional< migration_result >
 Get the result of the last migration cycle.
 
auto get_cumulative_stats () const -> migration_result
 Get total statistics since service started.
 
auto time_until_next_cycle () const -> std::optional< std::chrono::seconds >
 Get the time until the next scheduled migration.
 
auto cycles_completed () const noexcept -> std::size_t
 Get the number of cycles completed.
 
void set_migration_interval (std::chrono::seconds interval)
 Update the migration interval.
 
auto get_migration_interval () const noexcept -> std::chrono::seconds
 Get the current migration interval.
 
void set_progress_callback (migration_service_config::progress_callback callback)
 Set the progress callback.
 
void set_error_callback (migration_service_config::error_callback callback)
 Set the error callback.
 

Private Member Functions

void run_loop ()
 Background thread main loop.
 
auto execute_cycle () -> migration_result
 Execute a single migration cycle.
 
void update_stats (const migration_result &result)
 Update cumulative statistics.
 

Private Attributes

hsm_storage & storage_
 Reference to managed HSM storage.
 
std::shared_ptr< kcenon::thread::thread_pool > thread_pool_
 Thread pool for parallel migrations (optional)
 
migration_service_config config_
 Service configuration.
 
std::thread worker_thread_
 Background worker thread.
 
std::mutex mutex_
 Mutex for thread synchronization.
 
std::condition_variable cv_
 Condition variable for sleep/wake.
 
std::atomic< bool > stop_requested_ {false}
 Flag to signal shutdown.
 
std::atomic< bool > running_ {false}
 Flag indicating service is running.
 
std::atomic< bool > cycle_in_progress_ {false}
 Flag indicating a cycle is in progress.
 
std::optional< migration_result > last_result_
 Last migration result.
 
migration_result cumulative_stats_
 Cumulative statistics.
 
std::atomic< std::size_t > cycles_count_ {0}
 Number of completed cycles.
 
std::chrono::steady_clock::time_point next_cycle_time_
 Time of next scheduled cycle.
 

Detailed Description

Background migration service for HSM.

Runs periodic migration cycles to move data between storage tiers based on the configured tier policy. Integrates with thread_system for parallel migration operations.

Thread Safety:

  • All methods are thread-safe
  • Uses condition variables for efficient scheduling
  • Graceful shutdown support
Example:
// Create HSM storage
hsm_storage storage{hot, warm, cold};
// Create migration service
config.migration_interval = std::chrono::hours{1};
config.on_cycle_complete = [](const migration_result& r) {
std::cout << "Migrated " << r.instances_migrated << " instances\n";
};
hsm_migration_service service{storage, config};
service.start();
// Later...
service.stop();
Hierarchical Storage Management for multi-tier DICOM storage.
Definition hsm_storage.h:87
@ hot
Hot tier - Recent, frequently accessed data (SSD/NVMe)
@ cold
Cold tier - Archive, rarely accessed data (S3/Glacier)
@ warm
Warm tier - Older, occasionally accessed data (HDD)
Configuration for the migration service.
std::chrono::seconds migration_interval
Interval between migration cycles.

Definition at line 99 of file hsm_migration_service.h.

Constructor & Destructor Documentation

◆ hsm_migration_service() [1/4]

kcenon::pacs::storage::hsm_migration_service::hsm_migration_service ( hsm_storage & storage,
const migration_service_config & config = {} )
explicit

Construct migration service.

Parameters
storageReference to the HSM storage to manage
configService configuration

Definition at line 20 of file hsm_migration_service.cpp.

22 : storage_(storage), config_(config) {
23 if (config_.auto_start) {
24 start();
25 }
26}
hsm_storage & storage_
Reference to managed HSM storage.
migration_service_config config_
Service configuration.
void start()
Start the background migration service.
bool auto_start
Whether to start automatically on construction.

References kcenon::pacs::storage::migration_service_config::auto_start, and config_.

◆ hsm_migration_service() [2/4]

kcenon::pacs::storage::hsm_migration_service::hsm_migration_service ( hsm_storage & storage,
std::shared_ptr< kcenon::thread::thread_pool > thread_pool,
const migration_service_config & config = {} )

Construct migration service with thread pool.

Parameters
storageReference to the HSM storage to manage
thread_poolThread pool for parallel migrations
configService configuration

Definition at line 28 of file hsm_migration_service.cpp.

32 : storage_(storage),
33 thread_pool_(std::move(thread_pool)),
34 config_(config) {
35 if (config_.auto_start) {
36 start();
37 }
38}
std::shared_ptr< kcenon::thread::thread_pool > thread_pool_
Thread pool for parallel migrations (optional)

References kcenon::pacs::storage::migration_service_config::auto_start, and config_.

◆ ~hsm_migration_service()

kcenon::pacs::storage::hsm_migration_service::~hsm_migration_service ( )

Destructor - ensures graceful shutdown.

Definition at line 40 of file hsm_migration_service.cpp.

40 {
41 stop(true);
42}
void stop(bool wait_for_completion=true)
Stop the background migration service.

References stop().

Here is the call graph for this function:

◆ hsm_migration_service() [3/4]

kcenon::pacs::storage::hsm_migration_service::hsm_migration_service ( const hsm_migration_service & )
delete

Non-copyable.

◆ hsm_migration_service() [4/4]

kcenon::pacs::storage::hsm_migration_service::hsm_migration_service ( hsm_migration_service && )
delete

Non-movable.

Member Function Documentation

◆ cycles_completed()

auto kcenon::pacs::storage::hsm_migration_service::cycles_completed ( ) const -> std::size_t
nodiscardnoexcept

Get the number of cycles completed.

Returns
Total number of completed migration cycles

Definition at line 150 of file hsm_migration_service.cpp.

150 {
151 return cycles_count_.load();
152}
std::atomic< std::size_t > cycles_count_
Number of completed cycles.

References cycles_count_.

◆ execute_cycle()

auto kcenon::pacs::storage::hsm_migration_service::execute_cycle ( ) -> migration_result
nodiscardprivate

Execute a single migration cycle.

Returns
Migration result

Definition at line 227 of file hsm_migration_service.cpp.

227 {
228 cycle_in_progress_.store(true);
229
230 auto result = storage_.run_migration_cycle();
231
232 // Call error callbacks for failures
233 if (!result.failed_uids.empty() && config_.on_migration_error) {
234 for (const auto& uid : result.failed_uids) {
235 config_.on_migration_error(uid, "Migration failed");
236 }
237 }
238
239 cycle_in_progress_.store(false);
240
241 return result;
242}
std::atomic< bool > cycle_in_progress_
Flag indicating a cycle is in progress.
auto run_migration_cycle() -> migration_result
Run a single migration cycle.
std::string_view uid

References uid.

Referenced by run_loop().

Here is the caller graph for this function:

◆ get_cumulative_stats()

auto kcenon::pacs::storage::hsm_migration_service::get_cumulative_stats ( ) const -> migration_result
nodiscard

Get total statistics since service started.

Returns
Cumulative migration statistics

Definition at line 128 of file hsm_migration_service.cpp.

128 {
129 std::lock_guard lock(mutex_);
130 return cumulative_stats_;
131}
std::mutex mutex_
Mutex for thread synchronization.
migration_result cumulative_stats_
Cumulative statistics.

References cumulative_stats_, and mutex_.

◆ get_last_result()

auto kcenon::pacs::storage::hsm_migration_service::get_last_result ( ) const -> std::optional<migration_result>
nodiscard

Get the result of the last migration cycle.

Returns
Last migration result, or nullopt if no cycle has run

Definition at line 122 of file hsm_migration_service.cpp.

123 {
124 std::lock_guard lock(mutex_);
125 return last_result_;
126}
std::optional< migration_result > last_result_
Last migration result.

References last_result_, and mutex_.

◆ get_migration_interval()

auto kcenon::pacs::storage::hsm_migration_service::get_migration_interval ( ) const -> std::chrono::seconds
nodiscardnoexcept

Get the current migration interval.

Returns
Current interval between migration cycles

Definition at line 164 of file hsm_migration_service.cpp.

165 {
167}

References config_, and kcenon::pacs::storage::migration_service_config::migration_interval.

◆ is_running()

auto kcenon::pacs::storage::hsm_migration_service::is_running ( ) const -> bool
nodiscardnoexcept

Check if the service is running.

Returns
true if the background service is running

Definition at line 92 of file hsm_migration_service.cpp.

92 {
93 return running_.load();
94}
std::atomic< bool > running_
Flag indicating service is running.

References running_.

◆ operator=() [1/2]

hsm_migration_service & kcenon::pacs::storage::hsm_migration_service::operator= ( const hsm_migration_service & )
delete

◆ operator=() [2/2]

hsm_migration_service & kcenon::pacs::storage::hsm_migration_service::operator= ( hsm_migration_service && )
delete

◆ run_loop()

void kcenon::pacs::storage::hsm_migration_service::run_loop ( )
private

Background thread main loop.

Definition at line 185 of file hsm_migration_service.cpp.

185 {
186 while (!stop_requested_.load()) {
187 std::unique_lock lock(mutex_);
188
189 // Wait until next cycle time or stop requested
190 cv_.wait_until(lock, next_cycle_time_, [this]() {
191 return stop_requested_.load() ||
192 std::chrono::steady_clock::now() >= next_cycle_time_;
193 });
194
195 if (stop_requested_.load()) {
196 break;
197 }
198
199 // Release lock during migration
200 lock.unlock();
201
202 // Execute migration cycle
203 auto result = execute_cycle();
204
205 // Update statistics
206 update_stats(result);
207
208 // Store result
209 lock.lock();
210 last_result_ = result;
212
213 // Schedule next cycle
215 std::chrono::steady_clock::now() + config_.migration_interval;
216
217 // Call progress callback (outside of lock)
218 auto callback = config_.on_cycle_complete;
219 lock.unlock();
220
221 if (callback) {
222 callback(result);
223 }
224 }
225}
void update_stats(const migration_result &result)
Update cumulative statistics.
std::atomic< bool > stop_requested_
Flag to signal shutdown.
std::chrono::steady_clock::time_point next_cycle_time_
Time of next scheduled cycle.
auto execute_cycle() -> migration_result
Execute a single migration cycle.
std::condition_variable cv_
Condition variable for sleep/wake.

References config_, cv_, cycles_count_, execute_cycle(), last_result_, kcenon::pacs::storage::migration_service_config::migration_interval, mutex_, next_cycle_time_, kcenon::pacs::storage::migration_service_config::on_cycle_complete, stop_requested_, and update_stats().

Referenced by start().

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

◆ run_migration_cycle()

auto kcenon::pacs::storage::hsm_migration_service::run_migration_cycle ( ) -> migration_result
nodiscard

Manually trigger a migration cycle.

Runs a migration cycle immediately, regardless of the scheduled interval. Can be called whether the service is running or not.

Returns
Migration result with statistics

Definition at line 100 of file hsm_migration_service.cpp.

100 {
101 return execute_cycle();
102}

◆ set_error_callback()

void kcenon::pacs::storage::hsm_migration_service::set_error_callback ( migration_service_config::error_callback callback)

Set the error callback.

Parameters
callbackFunction called when a migration fails

Definition at line 175 of file hsm_migration_service.cpp.

176 {
177 std::lock_guard lock(mutex_);
178 config_.on_migration_error = std::move(callback);
179}

References config_, mutex_, and kcenon::pacs::storage::migration_service_config::on_migration_error.

◆ set_migration_interval()

void kcenon::pacs::storage::hsm_migration_service::set_migration_interval ( std::chrono::seconds interval)

Update the migration interval.

Parameters
intervalNew interval between migration cycles
Note
Takes effect at the next cycle

Definition at line 158 of file hsm_migration_service.cpp.

159 {
160 std::lock_guard lock(mutex_);
161 config_.migration_interval = interval;
162}

References config_, kcenon::pacs::storage::migration_service_config::migration_interval, and mutex_.

◆ set_progress_callback()

void kcenon::pacs::storage::hsm_migration_service::set_progress_callback ( migration_service_config::progress_callback callback)

Set the progress callback.

Parameters
callbackFunction called after each migration cycle

Definition at line 169 of file hsm_migration_service.cpp.

170 {
171 std::lock_guard lock(mutex_);
172 config_.on_cycle_complete = std::move(callback);
173}

References config_, mutex_, and kcenon::pacs::storage::migration_service_config::on_cycle_complete.

◆ start()

void kcenon::pacs::storage::hsm_migration_service::start ( )

Start the background migration service.

Starts the background thread that runs periodic migration cycles. If already started, this is a no-op.

Definition at line 48 of file hsm_migration_service.cpp.

48 {
49 std::lock_guard lock(mutex_);
50
51 if (running_.load()) {
52 return; // Already running
53 }
54
55 stop_requested_.store(false);
56 running_.store(true);
57
58 // Set next cycle time
60 std::chrono::steady_clock::now() + config_.migration_interval;
61
62 // Start worker thread
63 worker_thread_ = std::thread([this]() { run_loop(); });
64}
std::thread worker_thread_
Background worker thread.

References config_, kcenon::pacs::storage::migration_service_config::migration_interval, mutex_, next_cycle_time_, run_loop(), running_, stop_requested_, and worker_thread_.

Here is the call graph for this function:

◆ stop()

void kcenon::pacs::storage::hsm_migration_service::stop ( bool wait_for_completion = true)

Stop the background migration service.

Gracefully stops the service, waiting for any in-progress migrations to complete. If not started, this is a no-op.

Parameters
wait_for_completionIf true, waits for current cycle to complete

Definition at line 66 of file hsm_migration_service.cpp.

66 {
67 {
68 std::lock_guard lock(mutex_);
69
70 if (!running_.load()) {
71 return; // Not running
72 }
73
74 stop_requested_.store(true);
75 }
76
77 // Wake up the worker thread
78 cv_.notify_all();
79
80 // Wait for thread to finish
81 if (worker_thread_.joinable()) {
82 if (wait_for_completion) {
83 worker_thread_.join();
84 } else {
85 worker_thread_.detach();
86 }
87 }
88
89 running_.store(false);
90}

References cv_, mutex_, running_, stop_requested_, and worker_thread_.

Referenced by ~hsm_migration_service().

Here is the caller graph for this function:

◆ time_until_next_cycle()

auto kcenon::pacs::storage::hsm_migration_service::time_until_next_cycle ( ) const -> std::optional<std::chrono::seconds>
nodiscard

Get the time until the next scheduled migration.

Returns
Duration until next cycle, or nullopt if not scheduled

Definition at line 133 of file hsm_migration_service.cpp.

134 {
135 std::lock_guard lock(mutex_);
136
137 if (!running_.load()) {
138 return std::nullopt;
139 }
140
141 auto now = std::chrono::steady_clock::now();
142 if (next_cycle_time_ <= now) {
143 return std::chrono::seconds{0};
144 }
145
146 return std::chrono::duration_cast<std::chrono::seconds>(next_cycle_time_ -
147 now);
148}

References mutex_, next_cycle_time_, and running_.

◆ trigger_cycle()

void kcenon::pacs::storage::hsm_migration_service::trigger_cycle ( )

Trigger next cycle immediately.

Wakes up the background thread to run a migration cycle immediately, without waiting for the scheduled interval. Only works if service is running.

Definition at line 104 of file hsm_migration_service.cpp.

104 {
105 std::lock_guard lock(mutex_);
106
107 if (!running_.load()) {
108 return;
109 }
110
111 // Set next cycle time to now to trigger immediate execution
112 next_cycle_time_ = std::chrono::steady_clock::now();
113
114 // Wake up the worker thread
115 cv_.notify_all();
116}

References cv_, mutex_, next_cycle_time_, and running_.

◆ update_stats()

void kcenon::pacs::storage::hsm_migration_service::update_stats ( const migration_result & result)
private

Update cumulative statistics.

Parameters
resultResult from latest cycle

Definition at line 244 of file hsm_migration_service.cpp.

244 {
245 std::lock_guard lock(mutex_);
246
247 cumulative_stats_.instances_migrated += result.instances_migrated;
248 cumulative_stats_.bytes_migrated += result.bytes_migrated;
249 cumulative_stats_.duration += result.duration;
250 cumulative_stats_.instances_skipped += result.instances_skipped;
251
252 // Append failed UIDs (keep last N)
253 constexpr std::size_t kMaxFailedUids = 100;
254 for (const auto& uid : result.failed_uids) {
255 if (cumulative_stats_.failed_uids.size() >= kMaxFailedUids) {
258 }
260 }
261}
std::chrono::milliseconds duration
Duration of the migration operation.
Definition hsm_types.h:238
std::size_t bytes_migrated
Total bytes migrated.
Definition hsm_types.h:235
std::size_t instances_migrated
Number of instances successfully migrated.
Definition hsm_types.h:232
std::size_t instances_skipped
Number of instances that were skipped (not eligible)
Definition hsm_types.h:244
std::vector< std::string > failed_uids
SOP Instance UIDs that failed to migrate.
Definition hsm_types.h:241

References kcenon::pacs::storage::migration_result::bytes_migrated, cumulative_stats_, kcenon::pacs::storage::migration_result::duration, kcenon::pacs::storage::migration_result::failed_uids, kcenon::pacs::storage::migration_result::instances_migrated, kcenon::pacs::storage::migration_result::instances_skipped, mutex_, and uid.

Referenced by run_loop().

Here is the caller graph for this function:

Member Data Documentation

◆ config_

migration_service_config kcenon::pacs::storage::hsm_migration_service::config_
private

◆ cumulative_stats_

migration_result kcenon::pacs::storage::hsm_migration_service::cumulative_stats_
private

Cumulative statistics.

Definition at line 317 of file hsm_migration_service.h.

Referenced by get_cumulative_stats(), and update_stats().

◆ cv_

std::condition_variable kcenon::pacs::storage::hsm_migration_service::cv_
private

Condition variable for sleep/wake.

Definition at line 302 of file hsm_migration_service.h.

Referenced by run_loop(), stop(), and trigger_cycle().

◆ cycle_in_progress_

std::atomic<bool> kcenon::pacs::storage::hsm_migration_service::cycle_in_progress_ {false}
private

Flag indicating a cycle is in progress.

Definition at line 311 of file hsm_migration_service.h.

311{false};

◆ cycles_count_

std::atomic<std::size_t> kcenon::pacs::storage::hsm_migration_service::cycles_count_ {0}
private

Number of completed cycles.

Definition at line 320 of file hsm_migration_service.h.

320{0};

Referenced by cycles_completed(), and run_loop().

◆ last_result_

std::optional<migration_result> kcenon::pacs::storage::hsm_migration_service::last_result_
private

Last migration result.

Definition at line 314 of file hsm_migration_service.h.

Referenced by get_last_result(), and run_loop().

◆ mutex_

std::mutex kcenon::pacs::storage::hsm_migration_service::mutex_
mutableprivate

◆ next_cycle_time_

std::chrono::steady_clock::time_point kcenon::pacs::storage::hsm_migration_service::next_cycle_time_
private

Time of next scheduled cycle.

Definition at line 323 of file hsm_migration_service.h.

Referenced by run_loop(), start(), time_until_next_cycle(), and trigger_cycle().

◆ running_

std::atomic<bool> kcenon::pacs::storage::hsm_migration_service::running_ {false}
private

Flag indicating service is running.

Definition at line 308 of file hsm_migration_service.h.

308{false};

Referenced by is_running(), start(), stop(), time_until_next_cycle(), and trigger_cycle().

◆ stop_requested_

std::atomic<bool> kcenon::pacs::storage::hsm_migration_service::stop_requested_ {false}
private

Flag to signal shutdown.

Definition at line 305 of file hsm_migration_service.h.

305{false};

Referenced by run_loop(), start(), and stop().

◆ storage_

hsm_storage& kcenon::pacs::storage::hsm_migration_service::storage_
private

Reference to managed HSM storage.

Definition at line 287 of file hsm_migration_service.h.

◆ thread_pool_

std::shared_ptr<kcenon::thread::thread_pool> kcenon::pacs::storage::hsm_migration_service::thread_pool_
private

Thread pool for parallel migrations (optional)

Definition at line 290 of file hsm_migration_service.h.

◆ worker_thread_

std::thread kcenon::pacs::storage::hsm_migration_service::worker_thread_
private

Background worker thread.

Definition at line 296 of file hsm_migration_service.h.

Referenced by start(), and stop().


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