### Schedule and Advance Timer Events in C++ Source: https://github.com/jsnell/ratas/blob/master/README.org Demonstrates scheduling a TimerEvent with a callback, advancing the timer wheel, and verifying event execution. It also shows how to cancel a scheduled event. This example requires a TimerWheel instance and a TimerEvent object. ```cpp #include #include // Assuming TimerWheel and TimerEvent are defined elsewhere // For example: class TimerWheel { public: typedef std::function Callback; void schedule(TimerEvent* timer, int delay) {} void advance(int ticks) {} }; template class TimerEvent { public: TimerEvent(Func callback) : callback_(callback) {} void cancel() {} private: Func callback_; }; // Example Usage: void example() { typedef std::function Callback; TimerWheel timers; int count = 0; TimerEvent timer([&count] () { ++count; }); timers.schedule(&timer, 5); timers.advance(4); assert(count == 0); timers.advance(1); assert(count == 1); timers.schedule(&timer, 5); timer.cancel(); timers.advance(4); assert(count == 1); } ``` -------------------------------- ### TimerWheel::advance - Advancing Time and Executing Events in C++ Source: https://context7.com/jsnell/ratas/llms.txt Explains and demonstrates the TimerWheel::advance method for moving time forward and executing scheduled events. It includes examples of using the execution limit parameter to control the number of events processed per call and processing remaining events. ```cpp TimerWheel timers; std::vector execution_order; TimerEvent timer1([&]() { execution_order.push_back(1); }); TimerEvent timer2([&]() { execution_order.push_back(2); }); TimerEvent timer3([&]() { execution_order.push_back(3); }); // Schedule multiple timers timers.schedule(&timer1, 5); timers.schedule(&timer2, 5); // Same tick as timer1 timers.schedule(&timer3, 10); // Advance with execution limit bool completed = timers.advance(5, 1); // Execute max 1 event assert(!completed); // More events pending assert(execution_order.size() == 1); // Continue with delta=0 to process remaining events completed = timers.advance(0, 1); assert(!completed); assert(execution_order.size() == 2); // Finish processing tick 5 completed = timers.advance(0, 10); assert(completed); assert(execution_order.size() == 2); // Advance to tick 10 timers.advance(5); assert(execution_order.size() == 3); assert(timers.now() == 10); ``` -------------------------------- ### TimerWheel::schedule Source: https://context7.com/jsnell/ratas/llms.txt Details how to schedule a timer event to execute after a specified number of ticks from the current time. This includes examples of scheduling multiple timers and how rescheduling works. ```APIDOC ## TimerWheel::schedule - Schedule Timer Event ### Description Schedule an event to execute after a specified number of ticks from the current time. This method handles the placement of the timer into the appropriate wheel based on the delay. ### Method `void schedule(TimerEventBase* event, Tick delay)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **event** (*TimerEventBase* *) - Required - A pointer to the `TimerEventBase` object to schedule. - **delay** (*Tick*) - Required - The number of ticks from the current time after which the event should execute. ### Request Example ```cpp TimerWheel timers; int execution_count = 0; // Create multiple timer events TimerEvent short_timer([&]() { printf("Short timer fired at tick %lu\n", timers.now()); execution_count++; }); TimerEvent long_timer([&]() { printf("Long timer fired at tick %lu\n", timers.now()); execution_count++; }); // Schedule short timer for 10 ticks from now timers.schedule(&short_timer, 10); // Schedule long timer for 300 ticks (multiple wheel levels) timers.schedule(&long_timer, 300); // Advance to short timer timers.advance(10); assert(execution_count == 1); // Advance to long timer timers.advance(290); assert(execution_count == 2); // Rescheduling moves the timer to new slot timers.schedule(&short_timer, 5); timers.schedule(&short_timer, 10); // Overrides previous schedule timers.advance(5); assert(execution_count == 2); // Didn't fire timers.advance(5); assert(execution_count == 3); // Fires at tick 10 ``` ### Response No direct response, modifies internal timer state. ``` -------------------------------- ### TimerWheel - Main Timer Manager Source: https://context7.com/jsnell/ratas/llms.txt Demonstrates the core functionality of the TimerWheel, including creating, scheduling, and advancing timer events, as well as canceling timers. ```APIDOC ## TimerWheel - Main Timer Manager ### Description The `TimerWheel` class manages all timer events and advances time. It maintains a hierarchical structure of wheels operating at different time resolutions. ### Example Usage ```cpp #include #include "timer-wheel.h" typedef std::function Callback; TimerWheel timers; int count = 0; // Create a timer event with a lambda callback TimerEvent timer([&count] () { ++count; printf("Timer executed! Count: %d\n", count); }); // Schedule timer to execute 5 ticks from now timers.schedule(&timer, 5); // Advance time by 4 ticks - timer doesn't fire yet timers.advance(4); assert(count == 0); // Advance 1 more tick - timer fires timers.advance(1); assert(count == 1); // Schedule and cancel a timer timers.schedule(&timer, 10); assert(timer.active()); timer.cancel(); assert(!timer.active()); timers.advance(10); assert(count == 1); // Timer didn't fire ``` ``` -------------------------------- ### TimerWheel::schedule - Scheduling Timer Events in C++ Source: https://context7.com/jsnell/ratas/llms.txt Illustrates how to schedule timer events with different durations using TimerWheel::schedule. It shows scheduling short and long timers, advancing time to trigger them, and how rescheduling overwrites previous schedules. ```cpp TimerWheel timers; int execution_count = 0; // Create multiple timer events TimerEvent short_timer([&]() { printf("Short timer fired at tick %lu\n", timers.now()); execution_count++; }); TimerEvent long_timer([&]() { printf("Long timer fired at tick %lu\n", timers.now()); execution_count++; }); // Schedule short timer for 10 ticks from now timers.schedule(&short_timer, 10); // Schedule long timer for 300 ticks (multiple wheel levels) timers.schedule(&long_timer, 300); // Advance to short timer timers.advance(10); assert(execution_count == 1); // Advance to long timer timers.advance(290); assert(execution_count == 2); // Rescheduling moves the timer to new slot timers.schedule(&short_timer, 5); timers.schedule(&short_timer, 10); // Overrides previous schedule timers.advance(5); assert(execution_count == 2); // Didn't fire timers.advance(5); assert(execution_count == 3); // Fires at tick 10 ``` -------------------------------- ### Rescheduling Timers from Callbacks in C++ Source: https://context7.com/jsnell/ratas/llms.txt Demonstrates how to safely schedule, reschedule, and cancel timers from within their own callbacks using the Ratas TimerWheel. This is crucial for creating dynamic and responsive event-driven systems. It shows a periodic timer that reschedules itself and another timer that triggers a cascade timer. ```cpp TimerWheel timers; int periodic_count = 0; int cascade_count = 0; // Recursive timer that reschedules itself TimerEvent periodic_timer([&]() { periodic_count++; printf("Periodic execution #%d at tick %lu\n", periodic_count, timers.now()); if (periodic_count < 5) { // Reschedule for 10 ticks from now timers.schedule(&periodic_timer, 10); } }); // Timer that schedules another timer TimerEvent cascade_timer([&]() { cascade_count++; printf("Cascade timer fired at tick %lu\n", timers.now()); }); TimerEvent trigger_timer([&]() { printf("Trigger timer scheduling cascade\n"); // Safe to schedule other timers from callback timers.schedule(&cascade_timer, 5); }); // Start periodic timer timers.schedule(&periodic_timer, 10); // Start trigger timer timers.schedule(&trigger_timer, 15); // Execute periodic timer 5 times for (int i = 0; i < 5; i++) { timers.advance(10); assert(periodic_count == i + 1); } // Cascade timer executes 5 ticks after trigger timers.advance(5); // Trigger fires at tick 65 timers.advance(5); // Cascade fires at tick 70 assert(cascade_count == 1); ``` -------------------------------- ### TimerWheel - Main Timer Manager in C++ Source: https://context7.com/jsnell/ratas/llms.txt Demonstrates the basic usage of the TimerWheel class for scheduling, advancing time, and canceling timer events. It utilizes lambda functions as callbacks and asserts the state of timers and execution counts. ```cpp #include #include "timer-wheel.h" typedef std::function Callback; TimerWheel timers; int count = 0; // Create a timer event with a lambda callback TimerEvent timer([&count] () { ++count; printf("Timer executed! Count: %d\n", count); }); // Schedule timer to execute 5 ticks from now timers.schedule(&timer, 5); // Advance time by 4 ticks - timer doesn't fire yet timers.advance(4); assert(count == 0); // Advance 1 more tick - timer fires timers.advance(1); assert(count == 1); // Schedule and cancel a timer timers.schedule(&timer, 10); assert(timer.active()); timer.cancel(); assert(!timer.active()); timers.advance(10); assert(count == 1); // Timer didn't fire ``` -------------------------------- ### Define Executable Targets in CMake Source: https://github.com/jsnell/ratas/blob/master/CMakeLists.txt Defines two executable targets for the project: 'test_basic.testbin' and 'test_benchmark.testbin', specifying their respective source files. These executables are built as part of the CMake process. ```cmake add_executable(test_basic.testbin src/test/test_basic.cc) add_executable(test_benchmark.testbin src/test/test_benchmark.cc) ``` -------------------------------- ### Configure CMake Testing and Dependencies Source: https://github.com/jsnell/ratas/blob/master/CMakeLists.txt Enables testing within CMake and sets up a workaround for test dependencies. It adds a test target 'build_test_code' to ensure all tests are built before 'test_basic' is run, addressing limitations in CMake's test dependency handling. ```cmake enable_testing() add_test(test_basic bin/test_basic.testbin) # CMake test support is a total shitshow. The test targets don't have # a dependency on the test binary, and it's in fact impossible to add # any dependencies at all for a test target. This means that "make # test" will never do the right thing, but just run some random # previously compiled versions. # # All the workarounds suck. This one seems to suck the least; add a # test that builds the other tests, and then add this non-standard # test-only sequencing dependency to force that test to run first. add_test(build_test_code "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target all) set_tests_properties(test_basic PROPERTIES DEPENDS build_test_code) ``` -------------------------------- ### TimerWheel::schedule_in_range - Flexible Timer Scheduling in C++ Source: https://context7.com/jsnell/ratas/llms.txt Demonstrates the use of TimerWheel::schedule_in_range for scheduling events within a specified time window. This method allows the TimerWheel to optimize event placement and shows how it handles existing timers within the range. ```cpp TimerWheel timers; int count = 0; TimerEvent flexible_timer([&count]() { ++count; }); // Schedule between 256 and 512 ticks - wheel optimizes placement timers.schedule_in_range(&flexible_timer, 256, 512); Tick scheduled_at = timers.ticks_to_next_event(); assert(scheduled_at >= 256 && scheduled_at <= 512); // If timer already in range, it won't be rescheduled timers.schedule_in_range(&flexible_timer, 200, 600); assert(timers.ticks_to_next_event() == scheduled_at); // Unchanged // Schedule outside current range forces rescheduling timers.schedule_in_range(&flexible_timer, 100, 150); assert(timers.ticks_to_next_event() >= 100 && timers.ticks_to_next_event() <= 150); // Execute the timer timers.advance(timers.ticks_to_next_event()); assert(count == 1); ``` -------------------------------- ### Configure CMake Output Directories Source: https://github.com/jsnell/ratas/blob/master/CMakeLists.txt Sets the output directories for archives, libraries, and runtime binaries within the CMake build process. This ensures that compiled artifacts are placed in designated locations. ```cmake set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) ``` -------------------------------- ### Use MemberTimerEvent for Object Member Functions in C++ Source: https://github.com/jsnell/ratas/blob/master/README.org Illustrates how to use MemberTimerEvent to tie timed events to specific member functions of a class. It shows the initialization of MemberTimerEvent with a pointer to the member function and scheduling it using TimerWheel. This requires a TimerWheel and a class with a member function to be called. ```cpp // Assuming TimerWheel and MemberTimerEvent are defined elsewhere // For example: class TimerWheel { public: void schedule(void* timer, int delay) {} }; template class MemberTimerEvent { public: MemberTimerEvent(Owner* owner) : owner_(owner) {} private: Owner* owner_; }; // Example Usage: class Test { public: Test() : inc_timer_(this) { } void start(TimerWheel* timers) { timers->schedule(&inc_timer_, 10); } void on_inc() { count_++; } int count() { return count_; } private: MemberTimerEvent inc_timer_; int count_ = 0; }; ``` -------------------------------- ### TimerWheel::advance Source: https://context7.com/jsnell/ratas/llms.txt Explains how to advance the timer wheel by a specified number of ticks, triggering the execution of any scheduled events within that time frame, with options for execution limits. ```APIDOC ## TimerWheel::advance - Advance Time ### Description Advance the timer wheel by a specified number of ticks and execute scheduled events. This method is crucial for processing time-dependent operations. It can also be used to limit the number of events executed per advancement step. ### Method `bool advance(Tick delta, int max_executions = -1)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **delta** (*Tick*) - Required - The number of ticks to advance the timer wheel. - **max_executions** (*int*) - Optional - The maximum number of timer events to execute during this advancement. Defaults to -1, meaning no limit. ### Request Example ```cpp TimerWheel timers; std::vector execution_order; TimerEvent timer1([&]() { execution_order.push_back(1); }); TimerEvent timer2([&]() { execution_order.push_back(2); }); TimerEvent timer3([&]() { execution_order.push_back(3); }); // Schedule multiple timers timers.schedule(&timer1, 5); timers.schedule(&timer2, 5); // Same tick as timer1 timers.schedule(&timer3, 10); // Advance with execution limit bool completed = timers.advance(5, 1); // Execute max 1 event assert(!completed); // More events pending assert(execution_order.size() == 1); // Continue with delta=0 to process remaining events completed = timers.advance(0, 1); assert(!completed); assert(execution_order.size() == 2); // Finish processing tick 5 completed = timers.advance(0, 10); assert(completed); assert(execution_order.size() == 2); // Advance to tick 10 timers.advance(5); assert(execution_order.size() == 3); assert(timers.now() == 10); ``` ### Response #### Success Response (bool) - **completed** (*bool*) - Returns `true` if all events scheduled up to the advanced time have been executed, `false` otherwise. ``` -------------------------------- ### Timer Event Lifecycle Management with Automatic Cleanup (C++) Source: https://context7.com/jsnell/ratas/llms.txt This C++ snippet illustrates the `TimerEventInterface` for managing timer events, emphasizing automatic cancellation upon object destruction. It demonstrates both scoped timers that clean up automatically and manual cancellation using the `cancel()` method. Dependencies include `TimerWheel` and `TimerEvent`. ```cpp TimerWheel timers; int destructor_canceled = 0; { // Timer automatically cancels on destruction TimerEvent scoped_timer([&]() { printf("This won't execute\n"); }); timers.schedule(&scoped_timer, 100); assert(scoped_timer.active()); assert(scoped_timer.scheduled_at() == 100); // scoped_timer destructor calls cancel() automatically } timers.advance(100); // Timer was canceled by destructor, callback never executed // Manual cancel operations TimerEvent manual_timer([&]() { ++destructor_canceled; }); timers.schedule(&manual_timer, 50); assert(manual_timer.active()); // Safe to cancel multiple times manual_timer.cancel(); assert(!manual_timer.active()); manual_timer.cancel(); // No-op, safe timers.advance(50); assert(destructor_canceled == 0); // Check timer status TimerEvent status_timer([&]() { ++destructor_canceled; }); assert(!status_timer.active()); timers.schedule(&status_timer, 25); assert(status_timer.active()); assert(status_timer.scheduled_at() == timers.now() + 25); ``` -------------------------------- ### Set C++ and C Compiler Flags in CMake Source: https://github.com/jsnell/ratas/blob/master/CMakeLists.txt Configures C++ and C compiler flags for the project. These flags enable C++11 standard, debugging information, warning levels, and optimization. The flags are appended to existing ones. ```cmake set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g3 -Wall -Werror -Wno-sign-compare -O3") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -g3 -Wall -Werror -Wno-sign-compare -O3") ``` -------------------------------- ### TimerWheel::schedule_in_range Source: https://context7.com/jsnell/ratas/llms.txt Provides a method to schedule an event within a flexible time range, allowing the TimerWheel to optimize placement for minimal promotion overhead. ```APIDOC ## TimerWheel::schedule_in_range - Flexible Scheduling ### Description Schedule an event within a time range, allowing the `TimerWheel` to optimize placement to minimize promotion overhead. This method is useful when exact timing is not critical but a window of execution is acceptable. ### Method `void schedule_in_range(TimerEventBase* event, Tick min_delay, Tick max_delay)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **event** (*TimerEventBase* *) - Required - A pointer to the `TimerEventBase` object to schedule. - **min_delay** (*Tick*) - Required - The minimum number of ticks from the current time for the event to execute. - **max_delay** (*Tick*) - Required - The maximum number of ticks from the current time for the event to execute. ### Request Example ```cpp TimerWheel timers; int count = 0; TimerEvent flexible_timer([&count]() { ++count; }); // Schedule between 256 and 512 ticks - wheel optimizes placement timers.schedule_in_range(&flexible_timer, 256, 512); Tick scheduled_at = timers.ticks_to_next_event(); assert(scheduled_at >= 256 && scheduled_at <= 512); // If timer already in range, it won't be rescheduled timers.schedule_in_range(&flexible_timer, 200, 600); assert(timers.ticks_to_next_event() == scheduled_at); // Unchanged // Schedule outside current range forces rescheduling timers.schedule_in_range(&flexible_timer, 100, 150); assert(timers.ticks_to_next_event() >= 100 && timers.ticks_to_next_event() <= 150); // Execute the timer timers.advance(timers.ticks_to_next_event()); assert(count == 1); ``` ### Response No direct response, modifies internal timer state. ``` -------------------------------- ### Query Ticks Until Next Event (C++) Source: https://context7.com/jsnell/ratas/llms.txt This C++ code demonstrates the `TimerWheel::ticks_to_next_event` method, which returns the number of ticks until the next scheduled event. It covers cases with no events, with a maximum limit, and after partial event processing. Dependencies include `TimerWheel`, `TimerEvent`, and `std::numeric_limits`. ```cpp TimerWheel timers; // No events scheduled Tick next = timers.ticks_to_next_event(); assert(next == std::numeric_limits::max()); // With max parameter next = timers.ticks_to_next_event(1000); assert(next == 1000); // Returns max when no events TimerEvent timer1([]() {}); TimerEvent timer2([]() {}); // Schedule some events timers.schedule(&timer1, 50); assert(timers.ticks_to_next_event() == 50); timers.schedule(&timer2, 25); assert(timers.ticks_to_next_event() == 25); // Returns earliest // With max parameter limiting search timers.schedule(&timer1, 500); assert(timers.ticks_to_next_event(100) == 100); // Capped at max // After partial advance with max_execute limit timers.advance(1); timers.schedule(&timer1, 10); timers.schedule(&timer2, 10); timers.advance(10, 1); // Process only 1 event assert(timers.ticks_to_next_event() == 0); // Pending events at current tick // Finish processing timers.advance(0, 10); assert(timers.ticks_to_next_event(1000) == 1000); // No more events ``` -------------------------------- ### Bind Class Member Functions to Timer Events (C++) Source: https://context7.com/jsnell/ratas/llms.txt This snippet demonstrates how to bind member functions of a class to timer events using `MemberTimerEvent`. It showcases scheduling, execution, and managing retry logic within a `ConnectionManager` class. Dependencies include `TimerWheel` and `MemberTimerEvent`. ```cpp class ConnectionManager { public: ConnectionManager() : timeout_timer_(this), retry_timer_(this), connection_count_(0) { } void start(TimerWheel* timers) { timers_ = timers; // Schedule timeout check in 30 seconds timers_->schedule(&timeout_timer_, 30); } void on_timeout() { printf("Connection timeout at tick %lu\n", timers_->now()); // Schedule retry in 5 seconds timers_->schedule(&retry_timer_, 5); } void on_retry() { printf("Retrying connection at tick %lu\n", timers_->now()); connection_count_++; if (connection_count_ < 3) { // Retry again in 5 seconds timers_->schedule(&retry_timer_, 5); } } int connection_count() const { return connection_count_; } private: MemberTimerEvent timeout_timer_; MemberTimerEvent retry_timer_; TimerWheel* timers_; int connection_count_; }; // Usage TimerWheel timers; ConnectionManager manager; manager.start(&timers); timers.advance(30); // Triggers on_timeout timers.advance(5); // Triggers first retry timers.advance(5); // Triggers second retry timers.advance(5); // Triggers third retry assert(manager.connection_count() == 3); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.