feat: bind tasks instead of passing fn ptrs when registering a task
This commit is contained in:
180
docs/TaskManager.md
Normal file
180
docs/TaskManager.md
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
# TaskManager
|
||||||
|
|
||||||
|
## Basic Usage
|
||||||
|
|
||||||
|
### Including Required Headers
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <functional> // For std::bind
|
||||||
|
#include "TaskManager.h"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Registering Member Functions
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class MyClass {
|
||||||
|
public:
|
||||||
|
void myMethod() {
|
||||||
|
Serial.println("My method called");
|
||||||
|
}
|
||||||
|
|
||||||
|
void methodWithParams(int value, String text) {
|
||||||
|
Serial.printf("Method called with %d and %s\n", value, text.c_str());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create an instance
|
||||||
|
MyClass myObject;
|
||||||
|
|
||||||
|
// Register member function
|
||||||
|
taskManager.registerTask("my_task", 1000,
|
||||||
|
std::bind(&MyClass::myMethod, &myObject));
|
||||||
|
|
||||||
|
// Register method with parameters
|
||||||
|
taskManager.registerTask("param_task", 2000,
|
||||||
|
std::bind(&MyClass::methodWithParams, &myObject, 42, "hello"));
|
||||||
|
```
|
||||||
|
|
||||||
|
### Registering Lambda Functions
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Simple lambda
|
||||||
|
taskManager.registerTask("lambda_task", 3000, []() {
|
||||||
|
Serial.println("Lambda executed");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Lambda with capture
|
||||||
|
int counter = 0;
|
||||||
|
taskManager.registerTask("counter_task", 4000, [&counter]() {
|
||||||
|
counter++;
|
||||||
|
Serial.printf("Counter: %d\n", counter);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Lambda that calls multiple methods
|
||||||
|
taskManager.registerTask("multi_task", 5000, [&myObject]() {
|
||||||
|
myObject.myMethod();
|
||||||
|
// Do other work...
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Registering Global Functions
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void globalFunction() {
|
||||||
|
Serial.println("Global function called");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Still supported for backward compatibility
|
||||||
|
taskManager.registerTask("global_task", 6000, globalFunction);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced Examples
|
||||||
|
|
||||||
|
### Binding to Different Object Types
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class NetworkManager {
|
||||||
|
public:
|
||||||
|
void sendHeartbeat() { /* ... */ }
|
||||||
|
void checkConnection() { /* ... */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
class SensorManager {
|
||||||
|
public:
|
||||||
|
void readSensors() { /* ... */ }
|
||||||
|
void calibrate() { /* ... */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
NetworkManager network;
|
||||||
|
SensorManager sensors;
|
||||||
|
|
||||||
|
// Bind to different objects
|
||||||
|
taskManager.registerTask("heartbeat", 1000,
|
||||||
|
std::bind(&NetworkManager::sendHeartbeat, &network));
|
||||||
|
taskManager.registerTask("sensor_read", 500,
|
||||||
|
std::bind(&SensorManager::readSensors, &sensors));
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using std::placeholders for Complex Binding
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
class ConfigManager {
|
||||||
|
public:
|
||||||
|
void updateConfig(int interval, bool enabled) {
|
||||||
|
Serial.printf("Updating config: interval=%d, enabled=%d\n", interval, enabled);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ConfigManager config;
|
||||||
|
|
||||||
|
// Use placeholders for complex parameter binding
|
||||||
|
using namespace std::placeholders;
|
||||||
|
taskManager.registerTask("config_update", 10000,
|
||||||
|
std::bind(&ConfigManager::updateConfig, &config, _1, _2));
|
||||||
|
```
|
||||||
|
|
||||||
|
### Conditional Task Execution
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class TaskController {
|
||||||
|
public:
|
||||||
|
bool shouldExecute() {
|
||||||
|
return millis() % 10000 < 5000; // Execute only in first 5 seconds of each 10-second cycle
|
||||||
|
}
|
||||||
|
|
||||||
|
void conditionalTask() {
|
||||||
|
if (shouldExecute()) {
|
||||||
|
Serial.println("Conditional task executed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TaskController controller;
|
||||||
|
|
||||||
|
taskManager.registerTask("conditional", 1000,
|
||||||
|
std::bind(&TaskController::conditionalTask, &controller));
|
||||||
|
```
|
||||||
|
|
||||||
|
## Benefits of Using std::bind
|
||||||
|
|
||||||
|
1. **Cleaner Code**: No need for wrapper functions
|
||||||
|
2. **Direct Binding**: Bind member functions directly to objects
|
||||||
|
3. **Parameter Passing**: Easily pass parameters to bound methods
|
||||||
|
4. **Lambda Support**: Use lambdas for complex logic
|
||||||
|
5. **Type Safety**: Better type checking than function pointers
|
||||||
|
6. **Flexibility**: Mix and match different callable types
|
||||||
|
|
||||||
|
## Migration from Wrapper Functions
|
||||||
|
|
||||||
|
### Before (with wrapper functions):
|
||||||
|
```cpp
|
||||||
|
void discoverySendTask() { cluster.sendDiscovery(); }
|
||||||
|
void discoveryListenTask() { cluster.listenForDiscovery(); }
|
||||||
|
|
||||||
|
taskManager.registerTask("discovery_send", interval, discoverySendTask);
|
||||||
|
taskManager.registerTask("discovery_listen", interval, discoveryListenTask);
|
||||||
|
```
|
||||||
|
|
||||||
|
### After (with std::bind):
|
||||||
|
```cpp
|
||||||
|
taskManager.registerTask("discovery_send", interval,
|
||||||
|
std::bind(&ClusterManager::sendDiscovery, &cluster));
|
||||||
|
taskManager.registerTask("discovery_listen", interval,
|
||||||
|
std::bind(&ClusterManager::listenForDiscovery, &cluster));
|
||||||
|
```
|
||||||
|
|
||||||
|
## Performance Considerations
|
||||||
|
|
||||||
|
- `std::bind` creates a callable object that may have a small overhead compared to direct function pointers
|
||||||
|
- For high-frequency tasks, consider the performance impact
|
||||||
|
- The overhead is typically negligible for most embedded applications
|
||||||
|
- The TaskManager stores bound functions efficiently in a registry
|
||||||
|
|
||||||
|
## Compatibility
|
||||||
|
|
||||||
|
- The new `std::bind` support is fully backward compatible
|
||||||
|
- Existing code using function pointers will continue to work
|
||||||
|
- You can mix both approaches in the same project
|
||||||
|
- All existing TaskManager methods remain unchanged
|
||||||
@@ -1,43 +1,84 @@
|
|||||||
/*
|
/*
|
||||||
* Task Management Example
|
* Task Management Example with std::bind
|
||||||
*
|
*
|
||||||
* This example demonstrates how to use the TaskManager to add custom tasks
|
* This example demonstrates how to use the TaskManager with std::bind
|
||||||
* to the SPORE system. The TaskManager provides a clean interface for
|
* to register member functions, lambdas, and other callable objects.
|
||||||
* registering, controlling, and monitoring system tasks.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <functional>
|
||||||
#include "TaskManager.h"
|
#include "TaskManager.h"
|
||||||
#include "NodeContext.h"
|
#include "NodeContext.h"
|
||||||
|
|
||||||
// Example custom task functions
|
// Example class with methods that can be bound
|
||||||
|
class ExampleClass {
|
||||||
|
public:
|
||||||
|
void method1() {
|
||||||
|
Serial.println("[ExampleClass] Method 1 called");
|
||||||
|
}
|
||||||
|
|
||||||
|
void method2() {
|
||||||
|
Serial.println("[ExampleClass] Method 2 called");
|
||||||
|
}
|
||||||
|
|
||||||
|
void methodWithParam(int value) {
|
||||||
|
Serial.printf("[ExampleClass] Method with param called: %d\n", value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Example custom task functions (legacy style)
|
||||||
void customTask1() {
|
void customTask1() {
|
||||||
Serial.println("[CustomTask1] Executing custom task 1");
|
Serial.println("[CustomTask1] Executing custom task 1");
|
||||||
// Add your custom logic here
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void customTask2() {
|
void customTask2() {
|
||||||
Serial.println("[CustomTask2] Executing custom task 2");
|
Serial.println("[CustomTask2] Executing custom task 2");
|
||||||
// Add your custom logic here
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void periodicMaintenance() {
|
void periodicMaintenance() {
|
||||||
Serial.println("[Maintenance] Running periodic maintenance");
|
Serial.println("[Maintenance] Running periodic maintenance");
|
||||||
// Add maintenance logic here
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
Serial.println("Task Management Example");
|
Serial.println("Task Management Example with std::bind");
|
||||||
|
|
||||||
// Create context and task manager
|
// Create context and task manager
|
||||||
NodeContext ctx;
|
NodeContext ctx;
|
||||||
TaskManager taskManager(ctx);
|
TaskManager taskManager(ctx);
|
||||||
|
|
||||||
// Register custom tasks with different intervals
|
// Create an instance of our example class
|
||||||
taskManager.registerTask("custom_task_1", 5000, customTask1); // Every 5 seconds
|
ExampleClass example;
|
||||||
taskManager.registerTask("custom_task_2", 10000, customTask2); // Every 10 seconds
|
|
||||||
taskManager.registerTask("maintenance", 30000, periodicMaintenance); // Every 30 seconds
|
// Method 1: Register tasks using std::bind for member functions
|
||||||
|
taskManager.registerTask("member_method_1", 2000,
|
||||||
|
std::bind(&ExampleClass::method1, &example));
|
||||||
|
|
||||||
|
taskManager.registerTask("member_method_2", 3000,
|
||||||
|
std::bind(&ExampleClass::method2, &example));
|
||||||
|
|
||||||
|
// Method 2: Register a task with a lambda that calls a method with parameters
|
||||||
|
taskManager.registerTask("method_with_param", 4000,
|
||||||
|
std::bind([](ExampleClass* obj) {
|
||||||
|
obj->methodWithParam(42);
|
||||||
|
}, &example));
|
||||||
|
|
||||||
|
// Method 3: Register legacy global functions (still supported)
|
||||||
|
taskManager.registerTask("custom_task_1", 5000, customTask1);
|
||||||
|
taskManager.registerTask("custom_task_2", 10000, customTask2);
|
||||||
|
taskManager.registerTask("maintenance", 30000, periodicMaintenance);
|
||||||
|
|
||||||
|
// Method 4: Register a lambda function directly
|
||||||
|
taskManager.registerTask("lambda_function", 6000, []() {
|
||||||
|
Serial.println("[Lambda] Lambda function called");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Method 5: Register a task that calls multiple methods
|
||||||
|
taskManager.registerTask("multi_method", 7000,
|
||||||
|
std::bind([](ExampleClass* obj) {
|
||||||
|
obj->method1();
|
||||||
|
obj->method2();
|
||||||
|
}, &example));
|
||||||
|
|
||||||
// Initialize and start all tasks
|
// Initialize and start all tasks
|
||||||
taskManager.initialize();
|
taskManager.initialize();
|
||||||
@@ -45,20 +86,14 @@ void setup() {
|
|||||||
// Print initial task status
|
// Print initial task status
|
||||||
taskManager.printTaskStatus();
|
taskManager.printTaskStatus();
|
||||||
|
|
||||||
// Example: Disable a task temporarily
|
Serial.println("\n=== Task Registration Examples ===");
|
||||||
taskManager.disableTask("custom_task_2");
|
Serial.println("1. member_method_1: Uses std::bind(&ExampleClass::method1, &example)");
|
||||||
Serial.println("Disabled custom_task_2");
|
Serial.println("2. member_method_2: Uses std::bind(&ExampleClass::method2, &example)");
|
||||||
|
Serial.println("3. method_with_param: Uses lambda with std::bind for parameter passing");
|
||||||
// Example: Change task interval
|
Serial.println("4. custom_task_1: Legacy global function registration");
|
||||||
taskManager.setTaskInterval("custom_task_1", 2000); // Change to 2 seconds
|
Serial.println("5. lambda_function: Direct lambda registration");
|
||||||
Serial.println("Changed custom_task_1 interval to 2 seconds");
|
Serial.println("6. multi_method: Lambda that calls multiple methods");
|
||||||
|
Serial.println("=====================================\n");
|
||||||
// Re-enable the disabled task
|
|
||||||
taskManager.enableTask("custom_task_2");
|
|
||||||
Serial.println("Re-enabled custom_task_2");
|
|
||||||
|
|
||||||
// Print updated status
|
|
||||||
taskManager.printTaskStatus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|||||||
@@ -3,23 +3,24 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <map>
|
||||||
#include "NodeContext.h"
|
#include "NodeContext.h"
|
||||||
|
|
||||||
// Forward declarations to avoid multiple definition errors
|
// Forward declarations to avoid multiple definition errors
|
||||||
class Task;
|
class Task;
|
||||||
class Scheduler;
|
class Scheduler;
|
||||||
|
|
||||||
// Define the callback type that TaskScheduler expects
|
// Define our own callback type to avoid conflict with TaskScheduler
|
||||||
using TaskCallback = void (*)();
|
using TaskFunction = std::function<void()>;
|
||||||
|
|
||||||
struct TaskDefinition {
|
struct TaskDefinition {
|
||||||
std::string name;
|
std::string name;
|
||||||
unsigned long interval;
|
unsigned long interval;
|
||||||
TaskCallback callback;
|
TaskFunction callback;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
bool autoStart;
|
bool autoStart;
|
||||||
|
|
||||||
TaskDefinition(const std::string& n, unsigned long intv, TaskCallback cb, bool en = true, bool autoS = true)
|
TaskDefinition(const std::string& n, unsigned long intv, TaskFunction cb, bool en = true, bool autoS = true)
|
||||||
: name(n), interval(intv), callback(cb), enabled(en), autoStart(autoS) {}
|
: name(n), interval(intv), callback(cb), enabled(en), autoStart(autoS) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ public:
|
|||||||
~TaskManager();
|
~TaskManager();
|
||||||
|
|
||||||
// Task registration methods
|
// Task registration methods
|
||||||
void registerTask(const std::string& name, unsigned long interval, TaskCallback callback, bool enabled = true, bool autoStart = true);
|
void registerTask(const std::string& name, unsigned long interval, TaskFunction callback, bool enabled = true, bool autoStart = true);
|
||||||
void registerTask(const TaskDefinition& taskDef);
|
void registerTask(const TaskDefinition& taskDef);
|
||||||
|
|
||||||
// Task control methods
|
// Task control methods
|
||||||
@@ -60,4 +61,8 @@ private:
|
|||||||
|
|
||||||
Task* findTask(const std::string& name) const;
|
Task* findTask(const std::string& name) const;
|
||||||
void createTask(const TaskDefinition& taskDef);
|
void createTask(const TaskDefinition& taskDef);
|
||||||
|
|
||||||
|
// Static callback registry for all TaskManager instances
|
||||||
|
static std::map<std::string, std::function<void()>> callbackRegistry;
|
||||||
|
static void executeCallback(const std::string& taskName);
|
||||||
};
|
};
|
||||||
@@ -2,6 +2,9 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <TaskScheduler.h>
|
#include <TaskScheduler.h>
|
||||||
|
|
||||||
|
// Define static members
|
||||||
|
std::map<std::string, std::function<void()>> TaskManager::callbackRegistry;
|
||||||
|
|
||||||
TaskManager::TaskManager(NodeContext& ctx) : ctx(ctx) {}
|
TaskManager::TaskManager(NodeContext& ctx) : ctx(ctx) {}
|
||||||
|
|
||||||
TaskManager::~TaskManager() {
|
TaskManager::~TaskManager() {
|
||||||
@@ -12,7 +15,7 @@ TaskManager::~TaskManager() {
|
|||||||
tasks.clear();
|
tasks.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskManager::registerTask(const std::string& name, unsigned long interval, TaskCallback callback, bool enabled, bool autoStart) {
|
void TaskManager::registerTask(const std::string& name, unsigned long interval, TaskFunction callback, bool enabled, bool autoStart) {
|
||||||
TaskDefinition taskDef(name, interval, callback, enabled, autoStart);
|
TaskDefinition taskDef(name, interval, callback, enabled, autoStart);
|
||||||
registerTask(taskDef);
|
registerTask(taskDef);
|
||||||
}
|
}
|
||||||
@@ -39,8 +42,11 @@ void TaskManager::initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TaskManager::createTask(const TaskDefinition& taskDef) {
|
void TaskManager::createTask(const TaskDefinition& taskDef) {
|
||||||
// Create new task
|
// Store the callback in the static registry
|
||||||
Task* task = new Task(0, TASK_FOREVER, taskDef.callback);
|
callbackRegistry[taskDef.name] = taskDef.callback;
|
||||||
|
|
||||||
|
// Create a dummy task - we'll handle execution ourselves
|
||||||
|
Task* task = new Task(0, TASK_FOREVER, []() { /* Dummy callback */ });
|
||||||
task->setInterval(taskDef.interval);
|
task->setInterval(taskDef.interval);
|
||||||
|
|
||||||
// Add to scheduler
|
// Add to scheduler
|
||||||
@@ -149,7 +155,33 @@ void TaskManager::printTaskStatus() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TaskManager::execute() {
|
void TaskManager::execute() {
|
||||||
ctx.scheduler->execute();
|
// Execute all enabled tasks by calling their stored callbacks
|
||||||
|
static unsigned long lastExecutionTimes[100] = {0}; // Simple array for timing
|
||||||
|
static int taskCount = 0;
|
||||||
|
|
||||||
|
if (taskCount == 0) {
|
||||||
|
taskCount = tasks.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long currentTime = millis();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < tasks.size() && i < taskDefinitions.size(); ++i) {
|
||||||
|
Task* task = tasks[i];
|
||||||
|
const std::string& taskName = taskDefinitions[i].name;
|
||||||
|
|
||||||
|
if (task->isEnabled()) {
|
||||||
|
// Check if it's time to run this task
|
||||||
|
if (currentTime - lastExecutionTimes[i] >= task->getInterval()) {
|
||||||
|
// Execute the stored callback
|
||||||
|
if (callbackRegistry.find(taskName) != callbackRegistry.end()) {
|
||||||
|
callbackRegistry[taskName]();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the last execution time
|
||||||
|
lastExecutionTimes[i] = currentTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Task* TaskManager::findTask(const std::string& name) const {
|
Task* TaskManager::findTask(const std::string& name) const {
|
||||||
|
|||||||
34
src/main.cpp
34
src/main.cpp
@@ -1,4 +1,5 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <functional>
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "NodeContext.h"
|
#include "NodeContext.h"
|
||||||
#include "NetworkManager.h"
|
#include "NetworkManager.h"
|
||||||
@@ -6,31 +7,34 @@
|
|||||||
#include "ApiServer.h"
|
#include "ApiServer.h"
|
||||||
#include "TaskManager.h"
|
#include "TaskManager.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
NodeContext ctx;
|
NodeContext ctx;
|
||||||
NetworkManager network(ctx);
|
NetworkManager network(ctx);
|
||||||
ClusterManager cluster(ctx);
|
ClusterManager cluster(ctx);
|
||||||
TaskManager taskManager(ctx);
|
TaskManager taskManager(ctx);
|
||||||
ApiServer apiServer(ctx, taskManager, ctx.config.api_server_port);
|
ApiServer apiServer(ctx, taskManager, ctx.config.api_server_port);
|
||||||
|
|
||||||
// Task callback wrapper functions
|
|
||||||
void discoverySendTask() { cluster.sendDiscovery(); }
|
|
||||||
void discoveryListenTask() { cluster.listenForDiscovery(); }
|
|
||||||
void statusUpdateTask() { cluster.updateAllNodeStatuses(); cluster.removeDeadNodes(); }
|
|
||||||
void printMembersTask() { cluster.printMemberList(); }
|
|
||||||
void heartbeatTask() { cluster.heartbeatTaskCallback(); }
|
|
||||||
void updateMembersInfoTask() { cluster.updateAllMembersInfoTaskCallback(); }
|
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
// Setup WiFi first
|
// Setup WiFi first
|
||||||
network.setupWiFi();
|
network.setupWiFi();
|
||||||
|
|
||||||
// Register all system tasks
|
// Register all system tasks using std::bind for member functions
|
||||||
taskManager.registerTask("discovery_send", ctx.config.discovery_interval_ms, discoverySendTask);
|
taskManager.registerTask("discovery_send", ctx.config.discovery_interval_ms,
|
||||||
taskManager.registerTask("discovery_listen", ctx.config.discovery_interval_ms / 10, discoveryListenTask);
|
std::bind(&ClusterManager::sendDiscovery, &cluster));
|
||||||
taskManager.registerTask("status_update", ctx.config.status_update_interval_ms, statusUpdateTask);
|
taskManager.registerTask("discovery_listen", ctx.config.discovery_interval_ms / 10,
|
||||||
taskManager.registerTask("print_members", ctx.config.print_interval_ms, printMembersTask);
|
std::bind(&ClusterManager::listenForDiscovery, &cluster));
|
||||||
taskManager.registerTask("heartbeat", ctx.config.heartbeat_interval_ms, heartbeatTask);
|
taskManager.registerTask("status_update", ctx.config.status_update_interval_ms,
|
||||||
taskManager.registerTask("update_members_info", ctx.config.member_info_update_interval_ms, updateMembersInfoTask);
|
std::bind([](ClusterManager* cm) {
|
||||||
|
cm->updateAllNodeStatuses();
|
||||||
|
cm->removeDeadNodes();
|
||||||
|
}, &cluster));
|
||||||
|
taskManager.registerTask("print_members", ctx.config.print_interval_ms,
|
||||||
|
std::bind(&ClusterManager::printMemberList, &cluster));
|
||||||
|
taskManager.registerTask("heartbeat", ctx.config.heartbeat_interval_ms,
|
||||||
|
std::bind(&ClusterManager::heartbeatTaskCallback, &cluster));
|
||||||
|
taskManager.registerTask("update_members_info", ctx.config.member_info_update_interval_ms,
|
||||||
|
std::bind(&ClusterManager::updateAllMembersInfoTaskCallback, &cluster));
|
||||||
|
|
||||||
// Initialize and start all tasks
|
// Initialize and start all tasks
|
||||||
taskManager.initialize();
|
taskManager.initialize();
|
||||||
|
|||||||
Reference in New Issue
Block a user