Thread System 0.3.1
High-performance C++20 thread pool with work stealing and DAG scheduling
Loading...
Searching...
No Matches
integration_example.cpp File Reference

Integration of thread_system with external logger and monitoring services. More...

#include <iostream>
#include <chrono>
#include <thread>
#include <vector>
#include <kcenon/thread/interfaces/service_container.h>
#include <kcenon/thread/interfaces/thread_context.h>
#include <kcenon/thread/core/thread_pool.h>
#include <kcenon/thread/core/callback_job.h>
#include <kcenon/thread/core/log_level.h>
#include "mock_logger.h"
#include "mock_monitoring.h"
Include dependency graph for integration_example.cpp:

Go to the source code of this file.

Typedefs

using ILogger = kcenon::common::interfaces::ILogger
 
using IMonitor = kcenon::common::interfaces::IMonitor
 

Functions

void thread_pool_with_logger_example ()
 Example 1: Thread pool with external logger only.
 
void thread_pool_with_monitoring_example ()
 Example 2: Thread pool with external monitoring only.
 
void complete_integration_example ()
 Example 3: Complete integration with both logger and monitoring.
 
void dynamic_service_example ()
 Example 4: Dynamic service registration.
 
int main ()
 

Detailed Description

Integration of thread_system with external logger and monitoring services.

Definition in file integration_example.cpp.

Typedef Documentation

◆ ILogger

using ILogger = kcenon::common::interfaces::ILogger

Definition at line 42 of file integration_example.cpp.

◆ IMonitor

using IMonitor = kcenon::common::interfaces::IMonitor

Definition at line 43 of file integration_example.cpp.

Function Documentation

◆ complete_integration_example()

void complete_integration_example ( )

Example 3: Complete integration with both logger and monitoring.

Examples
integration_example.cpp.

Definition at line 203 of file integration_example.cpp.

203 {
204 std::cout << "\n=== Complete Integration Example ===\n" << std::endl;
205
206 // 1. Setup external services
207 auto logger = std::make_shared<mock_logger>();
208 auto monitor = std::make_shared<mock_monitoring>();
209
210 logger->start();
211 monitor->start();
212
213 // 2. Register both services
216
217 // 3. Create fully integrated thread pool
218 thread_context context;
219 auto pool = std::make_shared<thread_pool>("IntegratedPool", context);
220
221 // Log that we're starting
222 context.log(log_level_v2::info, "Starting integrated thread pool example");
223
224 // 4. Configure pool
225 std::vector<std::unique_ptr<thread_worker>> workers;
226 for (int i = 0; i < 4; ++i) {
227 workers.push_back(std::make_unique<thread_worker>(true)); // Enable timing
228 }
229 {
230 auto r = pool->enqueue_batch(std::move(workers));
231 if (r.is_err()) {
232 std::cerr << "enqueue_batch failed: " << r.error().message << std::endl;
233 return;
234 }
235 }
236 {
237 auto r = pool->start();
238 if (r.is_err()) {
239 std::cerr << "start failed: " << r.error().message << std::endl;
240 return;
241 }
242 }
243
244 // 5. Run workload with full instrumentation
245 std::cout << "Running workload with logging and monitoring..." << std::endl;
246
247 auto workload_start = std::chrono::steady_clock::now();
248
249 for (int i = 0; i < 50; ++i) {
250 auto r = pool->enqueue(std::make_unique<callback_job>(
251 [i, &context]() -> kcenon::common::VoidResult {
252 // Log job start
253 context.log(log_level_v2::debug,
254 "Job " + std::to_string(i) + " started");
255
256 // Simulate work
257 auto work_time = 20 + (i % 30);
258 std::this_thread::sleep_for(std::chrono::milliseconds(work_time));
259
260 // Simulate occasional warnings
261 if (i % 10 == 0) {
262 context.log(log_level_v2::warn,
263 "Job " + std::to_string(i) + " took longer than expected");
264 }
265
266 return kcenon::common::ok();
267 }
268 ));
269 if (r.is_err()) {
270 std::cerr << "enqueue failed: " << r.error().message << std::endl;
271 }
272 }
273
274 // 6. Monitor progress
275 for (int i = 0; i < 5; ++i) {
276 std::this_thread::sleep_for(std::chrono::milliseconds(300));
277
278 auto snapshot_result = monitor->get_metrics();
279 if (snapshot_result.is_ok()) {
280 context.log(log_level_v2::info,
281 "Progress: " + std::to_string(snapshot_result.value().metrics.size()) +
282 " metrics recorded");
283 }
284 }
285
286 // 7. Wait for completion
287 {
288 auto r = pool->stop();
289 if (r.is_err()) {
290 std::cerr << "stop failed: " << r.error().message << std::endl;
291 }
292 }
293
294 auto workload_end = std::chrono::steady_clock::now();
295 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
296 workload_end - workload_start);
297
298 context.log(log_level_v2::info,
299 "Workload completed in " + std::to_string(duration.count()) + " ms");
300
301 // 8. Final metrics
302 auto final_result = monitor->get_metrics();
303 if (final_result.is_ok()) {
304 const auto& final_snapshot = final_result.value();
305 std::cout << "\nFinal metrics:" << std::endl;
306 std::cout << " Total metrics collected: " << final_snapshot.metrics.size() << std::endl;
307 }
308
309 // 9. Cleanup
310 logger->stop();
311 monitor->stop();
313}
void register_singleton(std::shared_ptr< Implementation > instance)
Register a service with singleton lifetime.
void clear()
Clear all registered services.
static service_container & global()
Get the global service container instance.
Context object that provides access to optional services.
common::interfaces::ILogger ILogger
common::interfaces::IMonitor IMonitor

References kcenon::thread::service_container::clear(), kcenon::thread::service_container::global(), and kcenon::thread::service_container::register_singleton().

Referenced by main().

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

◆ dynamic_service_example()

void dynamic_service_example ( )

Example 4: Dynamic service registration.

Examples
integration_example.cpp.

Definition at line 318 of file integration_example.cpp.

318 {
319 std::cout << "\n=== Dynamic Service Registration Example ===\n" << std::endl;
320
321 // Create thread pool without any services
322 auto pool = std::make_shared<thread_pool>("DynamicPool");
323
324 std::vector<std::unique_ptr<thread_worker>> workers;
325 for (int i = 0; i < 2; ++i) {
326 workers.push_back(std::make_unique<thread_worker>());
327 }
328 {
329 auto r = pool->enqueue_batch(std::move(workers));
330 if (r.is_err()) {
331 std::cerr << "enqueue_batch failed: " << r.error().message << std::endl;
332 return;
333 }
334 }
335 {
336 auto r = pool->start();
337 if (r.is_err()) {
338 std::cerr << "start failed: " << r.error().message << std::endl;
339 return;
340 }
341 }
342
343 // Submit jobs without logging
344 std::cout << "Running without services..." << std::endl;
345 for (int i = 0; i < 5; ++i) {
346 auto r = pool->enqueue(std::make_unique<callback_job>(
347 []() -> kcenon::common::VoidResult {
348 std::this_thread::sleep_for(std::chrono::milliseconds(50));
349 return kcenon::common::ok();
350 }
351 ));
352 if (r.is_err()) {
353 std::cerr << "enqueue failed: " << r.error().message << std::endl;
354 }
355 }
356
357 std::this_thread::sleep_for(std::chrono::milliseconds(300));
358
359 // Now add logger dynamically
360 std::cout << "\nAdding logger service dynamically..." << std::endl;
361 auto logger = std::make_shared<mock_logger>();
362 logger->start();
364
365 // Create new context that will pick up the logger
366 thread_context new_context;
367
368 // Submit more jobs with logging
369 for (int i = 5; i < 10; ++i) {
370 auto r2 = pool->enqueue(std::make_unique<callback_job>(
371 [i, &new_context]() -> kcenon::common::VoidResult {
372 new_context.log(log_level_v2::info,
373 "Job " + std::to_string(i) + " with dynamic logger");
374 std::this_thread::sleep_for(std::chrono::milliseconds(50));
375 return kcenon::common::ok();
376 }
377 ));
378 if (r2.is_err()) {
379 std::cerr << "enqueue failed: " << r2.error().message << std::endl;
380 }
381 }
382
383 std::this_thread::sleep_for(std::chrono::milliseconds(600));
384
385 {
386 auto r = pool->stop();
387 if (r.is_err()) {
388 std::cerr << "stop failed: " << r.error().message << std::endl;
389 }
390 }
391 logger->stop();
393}

References kcenon::thread::service_container::clear(), kcenon::thread::service_container::global(), and kcenon::thread::service_container::register_singleton().

Referenced by main().

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

◆ main()

int main ( )

Definition at line 395 of file integration_example.cpp.

395 {
396 try {
397 std::cout << "=== Thread System Integration Examples ===" << std::endl;
398 std::cout << "Demonstrating integration with external logger and monitoring systems\n";
399
404
405 std::cout << "\n=== All integration examples completed successfully! ===" << std::endl;
406
407 } catch (const std::exception& e) {
408 std::cerr << "Error: " << e.what() << std::endl;
409 return 1;
410 }
411
412 return 0;
413}
void dynamic_service_example()
Example 4: Dynamic service registration.
void thread_pool_with_monitoring_example()
Example 2: Thread pool with external monitoring only.
void thread_pool_with_logger_example()
Example 1: Thread pool with external logger only.
void complete_integration_example()
Example 3: Complete integration with both logger and monitoring.

References complete_integration_example(), dynamic_service_example(), thread_pool_with_logger_example(), and thread_pool_with_monitoring_example().

Here is the call graph for this function:

◆ thread_pool_with_logger_example()

void thread_pool_with_logger_example ( )

Example 1: Thread pool with external logger only.

Examples
integration_example.cpp.

Definition at line 48 of file integration_example.cpp.

48 {
49 std::cout << "\n=== Thread Pool with External Logger ===\n" << std::endl;
50
51 // 1. Create and configure external logger
52 auto logger = std::make_shared<mock_logger>();
53 logger->start();
54
55 // 2. Register logger in service container
57
58 // 3. Create thread pool - it will automatically use the logger
59 thread_context context; // Resolves from global container
60 auto pool = std::make_shared<thread_pool>("LoggedPool", context);
61
62 // 4. Add workers
63 std::vector<std::unique_ptr<thread_worker>> workers;
64 for (int i = 0; i < 4; ++i) {
65 workers.push_back(std::make_unique<thread_worker>());
66 }
67 {
68 auto r = pool->enqueue_batch(std::move(workers));
69 if (r.is_err()) {
70 std::cerr << "enqueue_batch failed: " << r.error().message << std::endl;
71 return;
72 }
73 }
74
75 // 5. Start pool
76 {
77 auto r = pool->start();
78 if (r.is_err()) {
79 std::cerr << "start failed: " << r.error().message << std::endl;
80 return;
81 }
82 }
83
84 // 6. Submit jobs
85 for (int i = 0; i < 10; ++i) {
86 auto r = pool->enqueue(std::make_unique<callback_job>(
87 [i, &context]() -> kcenon::common::VoidResult {
88 // Job logs through context
89 context.log(log_level_v2::info,
90 "Executing job " + std::to_string(i));
91
92 // Simulate work
93 std::this_thread::sleep_for(std::chrono::milliseconds(50));
94
95 return kcenon::common::ok();
96 }
97 ));
98 if (r.is_err()) {
99 std::cerr << "enqueue failed: " << r.error().message << std::endl;
100 }
101 }
102
103 // 7. Wait and stop
104 std::this_thread::sleep_for(std::chrono::seconds(1));
105 {
106 auto r = pool->stop();
107 if (r.is_err()) {
108 std::cerr << "stop failed: " << r.error().message << std::endl;
109 }
110 }
111 logger->stop();
112
113 // 8. Clear service container
115}

References kcenon::thread::service_container::clear(), kcenon::thread::service_container::global(), and kcenon::thread::service_container::register_singleton().

Referenced by main().

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

◆ thread_pool_with_monitoring_example()

void thread_pool_with_monitoring_example ( )

Example 2: Thread pool with external monitoring only.

Examples
integration_example.cpp.

Definition at line 120 of file integration_example.cpp.

120 {
121 std::cout << "\n=== Thread Pool with External Monitoring ===\n" << std::endl;
122
123 // 1. Create and configure external monitoring
124 auto monitor = std::make_shared<mock_monitoring>();
125 monitor->start();
126
127 // 2. Register monitoring in service container
129
130 // 3. Create thread pool with monitoring
131 thread_context context;
132 auto pool = std::make_shared<thread_pool>("MonitoredPool", context);
133
134 // 4. Add workers and start
135 std::vector<std::unique_ptr<thread_worker>> workers;
136 for (int i = 0; i < 4; ++i) {
137 workers.push_back(std::make_unique<thread_worker>());
138 }
139 {
140 auto r = pool->enqueue_batch(std::move(workers));
141 if (r.is_err()) {
142 std::cerr << "enqueue_batch failed: " << r.error().message << std::endl;
143 return;
144 }
145 }
146 {
147 auto r = pool->start();
148 if (r.is_err()) {
149 std::cerr << "start failed: " << r.error().message << std::endl;
150 return;
151 }
152 }
153
154 // 5. Submit jobs and monitor
155 std::cout << "Submitting jobs and monitoring performance..." << std::endl;
156
157 for (int batch = 0; batch < 3; ++batch) {
158 // Submit batch of jobs
159 for (int i = 0; i < 20; ++i) {
160 auto r = pool->enqueue(std::make_unique<callback_job>(
161 [&context]() -> kcenon::common::VoidResult {
162 // Simulate varying workload
163 std::this_thread::sleep_for(
164 std::chrono::milliseconds(10 + rand() % 40));
165 return kcenon::common::ok();
166 }
167 ));
168 if (r.is_err()) {
169 std::cerr << "enqueue failed: " << r.error().message << std::endl;
170 }
171 }
172
173 // Wait and check metrics
174 std::this_thread::sleep_for(std::chrono::milliseconds(500));
175
176 auto snapshot_result = monitor->get_metrics();
177 if (snapshot_result.is_ok()) {
178 const auto& snapshot = snapshot_result.value();
179 std::cout << "Batch " << batch + 1 << " metrics:" << std::endl;
180 std::cout << " Total metrics recorded: " << snapshot.metrics.size() << std::endl;
181 }
182 }
183
184 // 6. Stop and get final stats
185 {
186 auto r = pool->stop();
187 if (r.is_err()) {
188 std::cerr << "stop failed: " << r.error().message << std::endl;
189 }
190 }
191 monitor->stop();
192
193 auto stats = monitor->get_stats();
194 std::cout << "\nFinal monitoring stats:" << std::endl;
195 std::cout << " Total collections: " << stats.total_collections << std::endl;
196
198}

References kcenon::thread::service_container::clear(), kcenon::thread::service_container::global(), and kcenon::thread::service_container::register_singleton().

Referenced by main().

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