PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
storage_query_exec_job.cpp
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
15
16#include <chrono>
17
19
21 service_handler handler,
22 completion_callback on_complete,
23 error_callback on_error)
24 : request_(std::move(request))
25 , handler_(std::move(handler))
26 , on_complete_(std::move(on_complete))
27 , on_error_(std::move(on_error)) {
28
33 context_.enqueue_time_ns = static_cast<uint64_t>(
34 std::chrono::duration_cast<std::chrono::nanoseconds>(
35 std::chrono::steady_clock::now().time_since_epoch()
36 ).count()
37 );
38}
39
41 -> VoidResult {
42
43 // Check if handler is set
44 if (!handler_) {
45 // Create default response (no handler means we need to reject)
46 service_result result;
47 result.session_id = request_.session_id;
48 result.message_id = request_.message_id;
49 result.presentation_context_id = request_.presentation_context_id;
50 result.sop_class_uid = request_.sop_class_uid;
51 result.sop_instance_uid = request_.sop_instance_uid;
53 result.error_comment = "No service handler configured";
54
55 // Determine response type
56 uint16_t cmd = static_cast<uint16_t>(request_.command_type);
57 result.response_type = static_cast<dimse_command_type>(cmd | 0x8000);
58
59 if (on_error_) {
60 on_error_(request_.session_id, "No service handler configured");
61 }
62
63 // Still submit to encode stage for proper response
64 auto encode_job = std::make_unique<response_encode_job>(std::move(result));
65 encode_job->get_context() = context_;
66 encode_job->get_context().stage = pipeline_stage::response_encode;
67
68 return coordinator.submit_to_stage(
70 std::move(encode_job)
71 );
72 }
73
74 // Execute the service handler
75 auto result = handler_(request_);
76
77 if (!result.is_ok()) {
78 if (on_error_) {
79 auto err = result.error();
80 on_error_(request_.session_id, err.message);
81 }
82
83 // Create error response
84 service_result error_response;
85 error_response.session_id = request_.session_id;
86 error_response.message_id = request_.message_id;
87 error_response.presentation_context_id = request_.presentation_context_id;
88 error_response.sop_class_uid = request_.sop_class_uid;
89 error_response.sop_instance_uid = request_.sop_instance_uid;
91 error_response.error_comment = result.error().message;
92
93 uint16_t cmd = static_cast<uint16_t>(request_.command_type);
94 error_response.response_type = static_cast<dimse_command_type>(cmd | 0x8000);
95
96 auto encode_job = std::make_unique<response_encode_job>(std::move(error_response));
97 encode_job->get_context() = context_;
98 encode_job->get_context().stage = pipeline_stage::response_encode;
99
100 return coordinator.submit_to_stage(
102 std::move(encode_job)
103 );
104 }
105
106 auto service_result_value = result.value();
107
108 // Invoke completion callback
109 if (on_complete_) {
110 on_complete_(service_result_value);
111 }
112
113 // Submit to encode stage
114 auto encode_job = std::make_unique<response_encode_job>(std::move(service_result_value));
115 encode_job->get_context() = context_;
116 encode_job->get_context().stage = pipeline_stage::response_encode;
117
118 return coordinator.submit_to_stage(
120 std::move(encode_job)
121 );
122}
123
124auto storage_query_exec_job::get_context() const noexcept -> const job_context& {
125 return context_;
126}
127
129 return context_;
130}
131
132auto storage_query_exec_job::get_name() const -> std::string {
133 return "storage_query_exec_job[session=" +
134 std::to_string(context_.session_id) +
135 ", cmd=" + std::to_string(static_cast<uint16_t>(request_.command_type)) +
136 ", msgid=" + std::to_string(request_.message_id) + "]";
137}
138
139auto storage_query_exec_job::get_request() const noexcept -> const dimse_request& {
140 return request_;
141}
142
170
171} // namespace kcenon::pacs::network::pipeline
Coordinates the 6-stage DICOM I/O pipeline.
storage_query_exec_job(dimse_request request, service_handler handler, completion_callback on_complete=nullptr, error_callback on_error=nullptr)
Construct an execution job.
auto get_name() const -> std::string override
Get the job name.
static auto get_category_for_command(dimse_command_type type) -> job_category
Determine job category from command type.
std::function< Result< service_result >(const dimse_request &)> service_handler
Service handler function type.
auto get_request() const noexcept -> const dimse_request &
Get the DIMSE request.
auto get_context() const noexcept -> const job_context &override
Get the job context.
std::function< void(const service_result &result)> completion_callback
Callback type for execution completion.
auto execute(pipeline_coordinator &coordinator) -> VoidResult override
Execute the storage/query operation.
std::function< void(uint64_t session_id, const std::string &error)> error_callback
Callback type for execution errors.
job_category
Categories for pipeline jobs used in metrics and monitoring.
@ move
C-MOVE move request/response.
@ store
C-STORE storage request/response.
@ get
C-GET retrieve request/response.
@ echo
C-ECHO verification request/response.
@ find
C-FIND query request/response.
dimse_command_type
DICOM DIMSE command types.
@ storage_query_exec
Stage 4: Execute storage/query operations (blocking allowed)
@ response_encode
Stage 5: Encode response into PDU bytes.
kcenon::pacs::VoidResult VoidResult
VoidResult type alias for operations without return value.
Definition association.h:59
Response encoding job for Stage 5 of the pipeline.
Storage and query execution job for Stage 4 of the pipeline.
Parsed DIMSE request for service execution.
dimse_command_type command_type
The DIMSE command type.
uint16_t message_id
Message ID for correlation.
Context information attached to pipeline jobs for tracking.
pipeline_stage stage
Current pipeline stage.
job_category category
Job category for metrics.
uint16_t message_id
Message ID from DIMSE command (if applicable)
uint64_t enqueue_time_ns
Timestamp when job entered the pipeline (nanoseconds since epoch)
uint64_t session_id
Session/association identifier.
uint8_t presentation_context_id
Presentation context ID.
uint64_t session_id
Session ID for routing response.
dimse_command_type response_type
Response command type.
std::string sop_class_uid
SOP Class UID (echoed back)
std::string sop_instance_uid
SOP Instance UID (echoed back)