Container System 0.1.0
High-performance C++20 type-safe container framework with SIMD-accelerated serialization
Loading...
Searching...
No Matches
async_coroutine_example.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
27#include <iostream>
28#include <memory>
29#include <vector>
30#include <chrono>
31#include <thread>
32#include <iomanip>
33#include <filesystem>
34
35#include "container.h"
36
37#if CONTAINER_HAS_COROUTINES
39#endif
40
41using namespace kcenon::container;
42
46void print_section(const std::string& title) {
47 std::cout << "\n" << std::string(60, '=') << std::endl;
48 std::cout << " " << title << std::endl;
49 std::cout << std::string(60, '=') << std::endl;
50}
51
55void print_success(const std::string& message) {
56 std::cout << "[OK] " << message << std::endl;
57}
58
62void print_error(const std::string& message) {
63 std::cout << "[ERROR] " << message << std::endl;
64}
65
66#if CONTAINER_HAS_COROUTINES
67
68using namespace kcenon::container::async;
69
73task<void> demonstrate_async_serialization() {
74 print_section("Async Serialization Demo");
75
76 // Create a container with some data
77 auto container = std::make_shared<value_container>();
78 container->set_message_type("async_demo");
79 container->set("name", std::string("John Doe"));
80 container->set("age", static_cast<int32_t>(30));
81 container->set("score", 95.5);
82 container->set("active", true);
83
84 std::cout << "Created container with 4 values" << std::endl;
85
86 // Wrap in async_container
87 async_container async_cont(container);
88
89 // Async serialize
90 std::cout << "Starting async serialization..." << std::endl;
91 auto start = std::chrono::steady_clock::now();
92
93#if CONTAINER_HAS_COMMON_RESULT
94 auto result = co_await async_cont.serialize_async();
95 if (result.is_ok()) {
96 auto& bytes = result.value();
97 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
98 std::chrono::steady_clock::now() - start).count();
99 print_success("Serialized " + std::to_string(bytes.size()) +
100 " bytes in " + std::to_string(duration) + " us");
101
102 // Async deserialize
103 std::cout << "Starting async deserialization..." << std::endl;
104 start = std::chrono::steady_clock::now();
105 auto deser_result = co_await async_container::deserialize_async(bytes);
106 if (deser_result.is_ok()) {
107 duration = std::chrono::duration_cast<std::chrono::microseconds>(
108 std::chrono::steady_clock::now() - start).count();
109 print_success("Deserialized in " + std::to_string(duration) + " us");
110
111 // Verify data
112 auto restored = deser_result.value();
113 auto name_val = restored->get("name");
114 if (name_val && std::holds_alternative<std::string>(name_val->data)) {
115 std::cout << "Verified: name = " <<
116 std::get<std::string>(name_val->data) << std::endl;
117 }
118 } else {
119 print_error("Deserialization failed");
120 }
121 } else {
122 print_error("Serialization failed");
123 }
124#else
125 auto bytes = co_await async_cont.serialize_async();
126 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
127 std::chrono::steady_clock::now() - start).count();
128 print_success("Serialized " + std::to_string(bytes.size()) +
129 " bytes in " + std::to_string(duration) + " us");
130
131 // Async deserialize
132 std::cout << "Starting async deserialization..." << std::endl;
133 start = std::chrono::steady_clock::now();
134 auto restored = co_await async_container::deserialize_async(bytes);
135 duration = std::chrono::duration_cast<std::chrono::microseconds>(
136 std::chrono::steady_clock::now() - start).count();
137 print_success("Deserialized in " + std::to_string(duration) + " us");
138#endif
139
140 co_return;
141}
142
146task<void> demonstrate_async_file_io() {
147 print_section("Async File I/O Demo");
148
149 // Create a container with data
150 auto container = std::make_shared<value_container>();
151 container->set_message_type("file_io_demo");
152
153 // Add some test data
154 for (int i = 0; i < 100; ++i) {
155 container->set("key_" + std::to_string(i),
156 std::string("value_") + std::to_string(i));
157 }
158 std::cout << "Created container with 100 key-value pairs" << std::endl;
159
160 async_container async_cont(container);
161
162 // Save to file
163 std::string temp_file = "/tmp/async_container_test.bin";
164 std::cout << "Saving to " << temp_file << "..." << std::endl;
165
166 auto start = std::chrono::steady_clock::now();
167
168#if CONTAINER_HAS_COMMON_RESULT
169 auto save_result = co_await async_cont.save_async(temp_file,
170 [](size_t bytes, size_t total) {
171 // Progress callback (optional)
172 });
173
174 if (save_result.is_ok()) {
175 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
176 std::chrono::steady_clock::now() - start).count();
177 print_success("Saved in " + std::to_string(duration) + " us");
178
179 // Load from file
180 async_container loaded_cont;
181 std::cout << "Loading from " << temp_file << "..." << std::endl;
182 start = std::chrono::steady_clock::now();
183
184 auto load_result = co_await loaded_cont.load_async(temp_file);
185 if (load_result.is_ok()) {
186 duration = std::chrono::duration_cast<std::chrono::microseconds>(
187 std::chrono::steady_clock::now() - start).count();
188 print_success("Loaded in " + std::to_string(duration) + " us");
189
190 // Verify data
191 auto loaded_container = loaded_cont.get_container();
192 auto val = loaded_container->get("key_50");
193 if (val && std::holds_alternative<std::string>(val->data)) {
194 std::cout << "Verified: key_50 = " <<
195 std::get<std::string>(val->data) << std::endl;
196 }
197 } else {
198 print_error("Load failed");
199 }
200 } else {
201 print_error("Save failed");
202 }
203#else
204 auto save_result = co_await async_cont.save_async(temp_file);
205 if (save_result) {
206 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
207 std::chrono::steady_clock::now() - start).count();
208 print_success("Saved in " + std::to_string(duration) + " us");
209
210 // Load from file
211 async_container loaded_cont;
212 std::cout << "Loading from " << temp_file << "..." << std::endl;
213 start = std::chrono::steady_clock::now();
214
215 auto load_result = co_await loaded_cont.load_async(temp_file);
216 if (load_result) {
217 duration = std::chrono::duration_cast<std::chrono::microseconds>(
218 std::chrono::steady_clock::now() - start).count();
219 print_success("Loaded in " + std::to_string(duration) + " us");
220 }
221 }
222#endif
223
224 // Cleanup
225 std::filesystem::remove(temp_file);
226 std::cout << "Cleaned up temp file" << std::endl;
227
228 co_return;
229}
230
234task<void> demonstrate_streaming() {
235 print_section("Streaming (Generator) Demo");
236
237 // Create a larger container
238 auto container = std::make_shared<value_container>();
239 container->set_message_type("streaming_demo");
240
241 // Add more data to make streaming meaningful
242 std::string large_data(10000, 'X');
243 for (int i = 0; i < 50; ++i) {
244 container->set("large_field_" + std::to_string(i), large_data);
245 }
246 std::cout << "Created container with 50 large fields" << std::endl;
247
248 async_container async_cont(container);
249
250 // Use generator to stream chunks
251 std::cout << "Streaming serialization in 8KB chunks:" << std::endl;
252
253 size_t chunk_count = 0;
254 size_t total_bytes = 0;
255 auto start = std::chrono::steady_clock::now();
256
257 for (auto chunk : async_cont.serialize_chunked(8 * 1024)) {
258 ++chunk_count;
259 total_bytes += chunk.size();
260 std::cout << " Chunk " << chunk_count << ": " << chunk.size() << " bytes" << std::endl;
261 }
262
263 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
264 std::chrono::steady_clock::now() - start).count();
265
266 print_success("Streamed " + std::to_string(total_bytes) + " bytes in " +
267 std::to_string(chunk_count) + " chunks (" +
268 std::to_string(duration) + " us)");
269
270 co_return;
271}
272
276task<void> demonstrate_executor_context() {
277 print_section("Executor Context Demo");
278
279 std::cout << "Using default executor (std::thread fallback)..." << std::endl;
280
281 auto container = std::make_shared<value_container>();
282 container->set_message_type("executor_demo");
283 container->set("test", std::string("value"));
284
285 async_container async_cont(container);
286
287 // Check if executor is available
288 auto& ctx = async_executor_context::instance();
289 if (ctx.has_executor()) {
290 std::cout << "Custom executor is configured" << std::endl;
291 } else {
292 std::cout << "Using default thread-based execution" << std::endl;
293 }
294
295 // Perform async operation
296 auto start = std::chrono::steady_clock::now();
297
298#if CONTAINER_HAS_COMMON_RESULT
299 auto result = co_await async_cont.serialize_async();
300 if (result.is_ok()) {
301 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
302 std::chrono::steady_clock::now() - start).count();
303 print_success("Operation completed in " + std::to_string(duration) + " us");
304 }
305#else
306 auto bytes = co_await async_cont.serialize_async();
307 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
308 std::chrono::steady_clock::now() - start).count();
309 print_success("Operation completed in " + std::to_string(duration) + " us");
310#endif
311
312 co_return;
313}
314
318task<void> run_all_demos() {
319 std::cout << std::string(60, '*') << std::endl;
320 std::cout << " Container System - Async Coroutine API Examples" << std::endl;
321 std::cout << std::string(60, '*') << std::endl;
322
323 co_await demonstrate_async_serialization();
324 co_await demonstrate_async_file_io();
325 co_await demonstrate_streaming();
326 co_await demonstrate_executor_context();
327
328 print_section("All Demos Complete");
329 std::cout << "The async API provides non-blocking operations using" << std::endl;
330 std::cout << "C++20 coroutines for efficient integration with" << std::endl;
331 std::cout << "async I/O frameworks and event loops." << std::endl;
332}
333
334#endif // CONTAINER_HAS_COROUTINES
335
336int main() {
337#if CONTAINER_HAS_COROUTINES
338 // Run the demo coroutine
339 auto demo_task = run_all_demos();
340
341 // Wait for completion (simple busy-wait for demo purposes)
342 while (!demo_task.done()) {
343 std::this_thread::sleep_for(std::chrono::milliseconds(1));
344 }
345
346 std::cout << "\nDemo completed successfully!" << std::endl;
347#else
348 std::cout << "C++20 coroutines are not available." << std::endl;
349 std::cout << "Please compile with a C++20 compliant compiler:" << std::endl;
350 std::cout << " - GCC 10+ (full support in 11+)" << std::endl;
351 std::cout << " - Clang 13+" << std::endl;
352 std::cout << " - MSVC 2019 16.8+" << std::endl;
353#endif
354
355 return 0;
356}
Main header for C++20 coroutine async support.
void print_error(const std::string &message)
Helper to print error message.
void print_section(const std::string &title)
Helper to print section headers.
void print_success(const std::string &message)
Helper to print success message.
Async wrapper for value_container operations.
std::shared_ptr< value_container > get_container() const noexcept
Get the underlying container.
task< bool > load_async(std::string_view path, progress_callback callback=nullptr)
Load container from file asynchronously.
Forward declaration of task.
Definition task.h:209