refactor: harmonize method names
This commit is contained in:
@@ -11,6 +11,31 @@ The TaskManager system provides:
|
||||
- **Status Monitoring**: View task status and configuration
|
||||
- **Automatic Lifecycle**: Tasks are automatically managed and executed
|
||||
|
||||
## Service Interface Integration
|
||||
|
||||
Services now implement a unified interface for both endpoint and task registration:
|
||||
|
||||
```cpp
|
||||
class MyService : public Service {
|
||||
public:
|
||||
void registerEndpoints(ApiServer& api) override {
|
||||
// Register HTTP endpoints
|
||||
api.registerEndpoint("/api/my/status", HTTP_GET,
|
||||
[this](AsyncWebServerRequest* request) { handleStatus(request); });
|
||||
}
|
||||
|
||||
void registerTasks(TaskManager& taskManager) override {
|
||||
// Register background tasks
|
||||
taskManager.registerTask("my_heartbeat", 2000,
|
||||
[this]() { sendHeartbeat(); });
|
||||
taskManager.registerTask("my_maintenance", 30000,
|
||||
[this]() { performMaintenance(); });
|
||||
}
|
||||
|
||||
const char* getName() const override { return "MyService"; }
|
||||
};
|
||||
```
|
||||
|
||||
## Basic Usage
|
||||
|
||||
```cpp
|
||||
@@ -27,6 +52,46 @@ taskManager.registerTask("maintenance", 30000, maintenanceFunction);
|
||||
taskManager.initialize();
|
||||
```
|
||||
|
||||
## Service Lifecycle
|
||||
|
||||
The Spore framework automatically manages service registration and task lifecycle:
|
||||
|
||||
### Service Registration Process
|
||||
|
||||
1. **Service Creation**: Services are created with required dependencies (NodeContext, TaskManager, etc.)
|
||||
2. **Service Registration**: Services are registered with the Spore framework via `spore.registerService()`
|
||||
3. **Endpoint Registration**: When `spore.begin()` is called, `registerEndpoints()` is called for each service
|
||||
4. **Task Registration**: Simultaneously, `registerTasks()` is called for each service
|
||||
5. **Task Initialization**: The TaskManager initializes all registered tasks
|
||||
6. **Execution**: Tasks run in the main loop when their intervals elapse
|
||||
|
||||
### Framework Integration
|
||||
|
||||
```cpp
|
||||
void setup() {
|
||||
spore.setup();
|
||||
|
||||
// Create service with dependencies
|
||||
MyService* service = new MyService(spore.getContext(), spore.getTaskManager());
|
||||
|
||||
// Register service (endpoints and tasks will be registered when begin() is called)
|
||||
spore.registerService(service);
|
||||
|
||||
// This triggers registerEndpoints() and registerTasks() for all services
|
||||
spore.begin();
|
||||
}
|
||||
```
|
||||
|
||||
### Dynamic Service Addition
|
||||
|
||||
Services can be added after the framework has started:
|
||||
|
||||
```cpp
|
||||
// Add service to running framework
|
||||
MyService* newService = new MyService(spore.getContext(), spore.getTaskManager());
|
||||
spore.registerService(newService); // Immediately registers endpoints and tasks
|
||||
```
|
||||
|
||||
## Task Registration Methods
|
||||
|
||||
### Using std::bind with Member Functions (Recommended)
|
||||
@@ -153,7 +218,62 @@ taskManager.registerTask("lambda_task", 2000,
|
||||
|
||||
## Adding Custom Tasks
|
||||
|
||||
### Method 1: Using std::bind (Recommended)
|
||||
### Method 1: Service Interface (Recommended)
|
||||
|
||||
1. **Create your service class implementing the Service interface**:
|
||||
```cpp
|
||||
class SensorService : public Service {
|
||||
public:
|
||||
SensorService(NodeContext& ctx, TaskManager& taskManager)
|
||||
: ctx(ctx), taskManager(taskManager) {}
|
||||
|
||||
void registerEndpoints(ApiServer& api) override {
|
||||
api.registerEndpoint("/api/sensor/status", HTTP_GET,
|
||||
[this](AsyncWebServerRequest* request) { handleStatus(request); });
|
||||
}
|
||||
|
||||
void registerTasks(TaskManager& taskManager) override {
|
||||
taskManager.registerTask("temp_read", 1000,
|
||||
[this]() { readTemperature(); });
|
||||
taskManager.registerTask("calibrate", 60000,
|
||||
[this]() { calibrateSensors(); });
|
||||
}
|
||||
|
||||
const char* getName() const override { return "SensorService"; }
|
||||
|
||||
private:
|
||||
NodeContext& ctx;
|
||||
TaskManager& taskManager;
|
||||
|
||||
void readTemperature() {
|
||||
// Read sensor logic
|
||||
Serial.println("Reading temperature");
|
||||
}
|
||||
|
||||
void calibrateSensors() {
|
||||
// Calibration logic
|
||||
Serial.println("Calibrating sensors");
|
||||
}
|
||||
|
||||
void handleStatus(AsyncWebServerRequest* request) {
|
||||
// Handle status request
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
2. **Register with Spore framework**:
|
||||
```cpp
|
||||
void setup() {
|
||||
spore.setup();
|
||||
|
||||
SensorService* sensorService = new SensorService(spore.getContext(), spore.getTaskManager());
|
||||
spore.registerService(sensorService);
|
||||
|
||||
spore.begin(); // This will call registerTasks() automatically
|
||||
}
|
||||
```
|
||||
|
||||
### Method 2: Direct TaskManager Registration
|
||||
|
||||
1. **Create your service class**:
|
||||
```cpp
|
||||
@@ -181,7 +301,7 @@ taskManager.registerTask("lambda_task", 2000,
|
||||
std::bind(&SensorService::calibrateSensors, &sensors));
|
||||
```
|
||||
|
||||
### Method 2: Traditional Functions
|
||||
### Method 3: Traditional Functions
|
||||
|
||||
1. **Define your task function**:
|
||||
```cpp
|
||||
@@ -308,13 +428,55 @@ curl -X POST http://192.168.1.100/api/tasks/control \
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use std::bind for member functions**: Cleaner than wrapper functions
|
||||
2. **Group related tasks**: Register multiple related operations in a single task
|
||||
1. **Use Service Interface**: Implement the Service interface for clean integration with the framework
|
||||
2. **Group related tasks**: Register multiple related operations in a single service
|
||||
3. **Monitor task health**: Use the status API to monitor task performance
|
||||
4. **Plan intervals carefully**: Balance responsiveness with system resources
|
||||
5. **Use descriptive names**: Make task names clear and meaningful
|
||||
6. **Separate concerns**: Use registerEndpoints() for HTTP API and registerTasks() for background work
|
||||
7. **Dependency injection**: Pass required dependencies (NodeContext, TaskManager) to service constructors
|
||||
|
||||
## Migration from Wrapper Functions
|
||||
## Migration to Service Interface
|
||||
|
||||
### Before (manual task registration in constructor):
|
||||
```cpp
|
||||
class MyService : public Service {
|
||||
public:
|
||||
MyService(TaskManager& taskManager) : taskManager(taskManager) {
|
||||
// Tasks registered in constructor
|
||||
taskManager.registerTask("heartbeat", 2000, [this]() { sendHeartbeat(); });
|
||||
}
|
||||
|
||||
void registerEndpoints(ApiServer& api) override {
|
||||
// Only endpoints registered here
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### After (using Service interface):
|
||||
```cpp
|
||||
class MyService : public Service {
|
||||
public:
|
||||
MyService(TaskManager& taskManager) : taskManager(taskManager) {
|
||||
// No task registration in constructor
|
||||
}
|
||||
|
||||
void registerEndpoints(ApiServer& api) override {
|
||||
// Register HTTP endpoints
|
||||
api.registerEndpoint("/api/my/status", HTTP_GET,
|
||||
[this](AsyncWebServerRequest* request) { handleStatus(request); });
|
||||
}
|
||||
|
||||
void registerTasks(TaskManager& taskManager) override {
|
||||
// Register background tasks
|
||||
taskManager.registerTask("heartbeat", 2000, [this]() { sendHeartbeat(); });
|
||||
}
|
||||
|
||||
const char* getName() const override { return "MyService"; }
|
||||
};
|
||||
```
|
||||
|
||||
### Migration from Wrapper Functions
|
||||
|
||||
### Before (with wrapper functions):
|
||||
```cpp
|
||||
@@ -335,11 +497,11 @@ taskManager.registerTask("cluster_listen", interval,
|
||||
|
||||
## 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
|
||||
- The new Service interface is fully backward compatible
|
||||
- Existing code using direct TaskManager registration will continue to work
|
||||
- You can mix Service interface and direct registration in the same project
|
||||
- All existing TaskManager methods remain unchanged
|
||||
- New status monitoring methods are additive and don't break existing functionality
|
||||
- The Service interface provides a cleaner, more organized approach for framework integration
|
||||
|
||||
## Related Documentation
|
||||
|
||||
|
||||
Reference in New Issue
Block a user