Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
timeoutQueue_example.C
Go to the documentation of this file.
1
36# include <iostream>
37# include <iomanip>
38# include <sstream>
39# include <atomic>
40# include <chrono>
41# include <thread>
42# include <timeoutQueue.H>
43
44using namespace std;
45
46// Helper to get current time plus milliseconds
48{
50}
51
52// Helper to format time for display
53static string format_time(const Time& t)
54{
55 ostringstream oss;
56 oss << t.tv_sec << "." << setfill('0') << setw(9) << t.tv_nsec;
57 return oss.str();
58}
59
60// Get current timestamp string for logging
61static string now_str()
62{
63 auto now = chrono::system_clock::now();
64 auto ms = chrono::duration_cast<chrono::milliseconds>(
65 now.time_since_epoch()) % 1000;
66 time_t tt = chrono::system_clock::to_time_t(now);
69
70 ostringstream oss;
71 oss << setfill('0') << setw(2) << local_tm.tm_hour << ":"
72 << setfill('0') << setw(2) << local_tm.tm_min << ":"
73 << setfill('0') << setw(2) << local_tm.tm_sec << "."
74 << setfill('0') << setw(3) << ms.count();
75 return oss.str();
76}
77
78// =============================================================================
79// Example 1: Simple Timed Event
80// =============================================================================
81
83{
84 string message;
85
86public:
87 SimpleEvent(const Time& t, const string& msg)
88 : Event(t), message(msg) {}
89
90 void EventFct() override
91 {
92 cout << "[" << now_str() << "] SimpleEvent: " << message << endl;
93 }
94};
95
97{
98 cout << "\n=== Demo 1: Simple Timed Event ===" << endl;
99 cout << "[" << now_str() << "] Scheduling event for 500ms from now..." << endl;
100
101 auto* event = new SimpleEvent(time_from_now_ms(500), "Hello from timed event!");
102 queue.schedule_event(event);
103
104 // Wait for execution
105 this_thread::sleep_for(chrono::milliseconds(700));
106 delete event;
107}
108
109// =============================================================================
110// Example 2: Multiple Events with Priority Ordering
111// =============================================================================
112
114{
116 atomic<bool>& executed_flag;
117
118public:
119 NumberedEvent(const Time& t, int num, atomic<bool>& flag)
120 : Event(t), number(num), executed_flag(flag) {}
121
122 void EventFct() override
123 {
124 cout << "[" << now_str() << "] Event #" << number << " executed" << endl;
125 executed_flag = true;
126 }
127};
128
130{
131 cout << "\n=== Demo 2: Multiple Events Execute in Time Order ===" << endl;
132
133 atomic<bool> flags[4] = {false, false, false, false};
134
135 // Schedule events in non-chronological order
136 cout << "[" << now_str() << "] Scheduling events out of order..." << endl;
137
138 auto* e3 = new NumberedEvent(time_from_now_ms(300), 3, flags[2]);
139 auto* e1 = new NumberedEvent(time_from_now_ms(100), 1, flags[0]);
140 auto* e4 = new NumberedEvent(time_from_now_ms(400), 4, flags[3]);
141 auto* e2 = new NumberedEvent(time_from_now_ms(200), 2, flags[1]);
142
143 queue.schedule_event(e3);
144 queue.schedule_event(e1);
145 queue.schedule_event(e4);
146 queue.schedule_event(e2);
147
148 cout << " Events scheduled: #3 @300ms, #1 @100ms, #4 @400ms, #2 @200ms" << endl;
149 cout << " Expected order: 1, 2, 3, 4" << endl;
150
151 // Wait for all events
152 this_thread::sleep_for(chrono::milliseconds(600));
153
154 delete e1;
155 delete e2;
156 delete e3;
157 delete e4;
158}
159
160// =============================================================================
161// Example 3: Event Cancellation
162// =============================================================================
163
165{
166 string name;
167
168public:
169 CancellableEvent(const Time& t, const string& n)
170 : Event(t), name(n) {}
171
172 void EventFct() override
173 {
174 cout << "[" << now_str() << "] CancellableEvent '" << name << "' executed" << endl;
175 }
176
177 const string& get_name() const { return name; }
178};
179
181{
182 cout << "\n=== Demo 3: Event Cancellation ===" << endl;
183
184 auto* keep_event = new CancellableEvent(time_from_now_ms(200), "KEEP");
185 auto* cancel_event = new CancellableEvent(time_from_now_ms(300), "CANCEL");
186
188 queue.schedule_event(cancel_event);
189
190 cout << "[" << now_str() << "] Scheduled 'KEEP' @200ms and 'CANCEL' @300ms" << endl;
191
192 // Cancel one event
193 this_thread::sleep_for(chrono::milliseconds(50));
194 bool canceled = queue.cancel_event(cancel_event);
195 cout << "[" << now_str() << "] Canceled 'CANCEL' event: "
196 << (canceled ? "success" : "failed") << endl;
197 cout << " Event status: "
198 << (cancel_event->get_execution_status() == TimeoutQueue::Event::Canceled
199 ? "Canceled" : "Other") << endl;
200
201 // Wait and observe
202 this_thread::sleep_for(chrono::milliseconds(400));
203 cout << " Only 'KEEP' should have executed above." << endl;
204
205 delete keep_event;
206 delete cancel_event;
207}
208
209// =============================================================================
210// Example 4: Event Rescheduling
211// =============================================================================
212
214{
215 string name;
217
218public:
219 ReschedulableEvent(const Time& t, const string& n)
220 : Event(t), name(n) {}
221
222 void EventFct() override
223 {
225 cout << "[" << now_str() << "] ReschedulableEvent '" << name
226 << "' executed (count: " << execution_count << ")" << endl;
227 }
228
229 int get_count() const { return execution_count; }
230};
231
233{
234 cout << "\n=== Demo 4: Event Rescheduling ===" << endl;
235
236 auto* event = new ReschedulableEvent(time_from_now_ms(500), "Rescheduled");
237
238 cout << "[" << now_str() << "] Originally scheduled for 500ms" << endl;
239 queue.schedule_event(event);
240
241 // Reschedule to earlier time
242 this_thread::sleep_for(chrono::milliseconds(100));
243 cout << "[" << now_str() << "] Rescheduling to 100ms from now (200ms total)" << endl;
245
246 this_thread::sleep_for(chrono::milliseconds(300));
247 cout << " Event executed early due to rescheduling." << endl;
248
249 delete event;
250}
251
252// =============================================================================
253// Example 5: Self-Rescheduling Periodic Event
254// =============================================================================
255
257{
259 string name;
262
263public:
264 PeriodicEvent(const Time& t, TimeoutQueue* q, const string& n,
265 int interval, int max_exec)
266 : Event(t), queue(q), name(n), interval_ms(interval),
268
269 void EventFct() override
270 {
271 cout << "[" << now_str() << "] PeriodicEvent '" << name
272 << "' tick (remaining: " << remaining_executions - 1 << ")" << endl;
273
275 if (remaining_executions > 0)
277 }
278
279 bool is_done() const { return remaining_executions <= 0; }
280};
281
283{
284 cout << "\n=== Demo 5: Self-Rescheduling Periodic Event ===" << endl;
285
286 auto* periodic = new PeriodicEvent(
287 time_from_now_ms(100), &queue, "Heartbeat", 150, 4);
288
289 cout << "[" << now_str() << "] Starting periodic event (4 ticks, 150ms interval)" << endl;
291
292 // Wait for all executions: 100 + 3*150 = 550ms + buffer
293 this_thread::sleep_for(chrono::milliseconds(800));
294
295 delete periodic;
296}
297
298// =============================================================================
299// Example 6: Event with Callback
300// =============================================================================
301
303{
305
306public:
307 CallbackEvent(const Time& t, function<void()> cb)
308 : Event(t), callback(move(cb)) {}
309
310 void EventFct() override
311 {
312 if (callback)
313 callback();
314 }
315};
316
318{
319 cout << "\n=== Demo 6: Event with Lambda Callback ===" << endl;
320
321 int counter = 0;
322
323 auto* event1 = new CallbackEvent(time_from_now_ms(100), [&counter]() {
324 ++counter;
325 cout << "[" << now_str() << "] Lambda callback 1, counter = " << counter << endl;
326 });
327
328 auto* event2 = new CallbackEvent(time_from_now_ms(200), [&counter]() {
329 ++counter;
330 cout << "[" << now_str() << "] Lambda callback 2, counter = " << counter << endl;
331 });
332
333 queue.schedule_event(event1);
334 queue.schedule_event(event2);
335
336 this_thread::sleep_for(chrono::milliseconds(400));
337
338 cout << " Final counter value: " << counter << endl;
339
340 delete event1;
341 delete event2;
342}
343
344// =============================================================================
345// Example 7: Event Status Inspection
346// =============================================================================
347
348void print_status(const TimeoutQueue::Event* e, const string& name)
349{
350 const char* status_names[] = {
351 "Out_Queue", "In_Queue", "Canceled", "Executing", "Executed", "To_Delete", "Deleted"
352 };
353 cout << " " << name << " status: "
354 << status_names[static_cast<int>(e->get_execution_status())] << endl;
355}
356
358{
359 cout << "\n=== Demo 7: Event Lifecycle Status ===" << endl;
360
361 auto* event = new SimpleEvent(time_from_now_ms(200), "Status demo");
362
363 cout << "[" << now_str() << "] Event created:" << endl;
364 print_status(event, "event");
365
366 queue.schedule_event(event);
367 cout << "[" << now_str() << "] After scheduling:" << endl;
368 print_status(event, "event");
369
370 this_thread::sleep_for(chrono::milliseconds(300));
371 cout << "[" << now_str() << "] After execution:" << endl;
372 print_status(event, "event");
373
374 delete event;
375}
376
377// =============================================================================
378// Example 8: Cancel and Delete
379// =============================================================================
380
382{
383 cout << "\n=== Demo 8: Cancel and Delete Event ===" << endl;
384
385 TimeoutQueue::Event* event = new SimpleEvent(time_from_now_ms(500), "To be deleted");
386
387 cout << "[" << now_str() << "] Event pointer before: " << event << endl;
388 queue.schedule_event(event);
389
390 this_thread::sleep_for(chrono::milliseconds(100));
392
393 cout << "[" << now_str() << "] Event pointer after cancel_delete: " << event << endl;
394 cout << " (Should be nullptr - memory freed by cancel_delete_event)" << endl;
395}
396
397// =============================================================================
398// Main
399// =============================================================================
400
401int main()
402{
403 cout << "========================================" << endl;
404 cout << " TimeoutQueue Example Demonstrations " << endl;
405 cout << "========================================" << endl;
406
407 TimeoutQueue queue;
408
409 try
410 {
411 demo_simple_event(queue);
413 demo_cancellation(queue);
414 demo_rescheduling(queue);
415 demo_periodic_event(queue);
416 demo_callback_event(queue);
417 demo_event_status(queue);
418 demo_cancel_delete(queue);
419
420 cout << "\n=== Shutdown ===" << endl;
421 cout << "[" << now_str() << "] Calling queue.shutdown()..." << endl;
422 queue.shutdown();
423
424 // Wait for background thread to finish
425 this_thread::sleep_for(chrono::milliseconds(100));
426 cout << "[" << now_str() << "] Queue shut down successfully." << endl;
427 }
428 catch (const exception& e)
429 {
430 cerr << "Error: " << e.what() << endl;
431 queue.shutdown();
432 return 1;
433 }
434
435 cout << "\n========================================" << endl;
436 cout << " All demonstrations completed! " << endl;
437 cout << "========================================" << endl;
438
439 return 0;
440}
Time time_plus_msec(const Time &current_time, const int &msec)
Definition ah-time.H:112
Time read_current_time()
Definition ah-time.H:103
struct timespec Time
Definition ah-time.H:50
function< void()> callback
void EventFct() override
Event handler function to be overridden.
CallbackEvent(const Time &t, function< void()> cb)
void EventFct() override
Event handler function to be overridden.
CancellableEvent(const Time &t, const string &n)
const string & get_name() const
NumberedEvent(const Time &t, int num, atomic< bool > &flag)
void EventFct() override
Event handler function to be overridden.
atomic< bool > & executed_flag
TimeoutQueue * queue
void EventFct() override
Event handler function to be overridden.
PeriodicEvent(const Time &t, TimeoutQueue *q, const string &n, int interval, int max_exec)
ReschedulableEvent(const Time &t, const string &n)
void EventFct() override
Event handler function to be overridden.
void EventFct() override
Event handler function to be overridden.
SimpleEvent(const Time &t, const string &msg)
Base class for scheduled events.
Event(const Time &t, std::string name="")
@ Canceled
Removed from queue before execution.
Execution_Status get_execution_status() const
Thread-safe priority queue for scheduling timed events.
void reschedule_event(const Time &trigger_time, Event *event)
Reschedule an event to a new time.
void schedule_event(const Time &trigger_time, Event *)
Schedule an event at a specific time.
void cancel_delete_event(Event *&event)
Cancel and delete an event.
void shutdown()
Shut down the queue and stop the background thread.
bool cancel_event(Event *event)
Cancel a scheduled event.
DynList< T > maps(const C &c, Op op)
Classic map operation.
STL namespace.
Priority queue for scheduling timed events.
void demo_rescheduling(TimeoutQueue &queue)
static string format_time(const Time &t)
void print_status(const TimeoutQueue::Event *e, const string &name)
void demo_periodic_event(TimeoutQueue &queue)
void demo_event_status(TimeoutQueue &queue)
void demo_cancellation(TimeoutQueue &queue)
static string now_str()
void demo_callback_event(TimeoutQueue &queue)
void demo_priority_ordering(TimeoutQueue &queue)
void demo_cancel_delete(TimeoutQueue &queue)
void demo_simple_event(TimeoutQueue &queue)
int main()
static Time time_from_now_ms(int ms)