feat: task manager endpoint, updated documentation

This commit is contained in:
2025-08-22 15:47:08 +02:00
parent d7d307e3ce
commit 30a5f8b8cb
14 changed files with 2550 additions and 551 deletions

348
docs/TaskManagement.md Normal file
View File

@@ -0,0 +1,348 @@
# Task Management System
The SPORE system includes a comprehensive TaskManager that provides a clean interface for managing system tasks. This makes it easy to add, configure, and control background tasks without cluttering the main application code.
## Overview
The TaskManager system provides:
- **Easy Task Registration**: Simple API for adding new tasks with configurable intervals
- **Dynamic Control**: Enable/disable tasks at runtime
- **Interval Management**: Change task execution frequency on the fly
- **Status Monitoring**: View task status and configuration
- **Automatic Lifecycle**: Tasks are automatically managed and executed
## Basic Usage
```cpp
#include "TaskManager.h"
// Create task manager
TaskManager taskManager(ctx);
// Register tasks
taskManager.registerTask("heartbeat", 2000, heartbeatFunction);
taskManager.registerTask("maintenance", 30000, maintenanceFunction);
// Initialize and start all tasks
taskManager.initialize();
```
## Task Registration Methods
### Using std::bind with Member Functions (Recommended)
```cpp
#include <functional>
#include "TaskManager.h"
class MyService {
public:
void sendHeartbeat() {
Serial.println("Service heartbeat");
}
void performMaintenance() {
Serial.println("Running maintenance");
}
};
MyService service;
TaskManager taskManager(ctx);
// Register member functions using std::bind
taskManager.registerTask("heartbeat", 2000,
std::bind(&MyService::sendHeartbeat, &service));
taskManager.registerTask("maintenance", 30000,
std::bind(&MyService::performMaintenance, &service));
// Initialize and start all tasks
taskManager.initialize();
```
### Using Lambda Functions
```cpp
// Register lambda functions directly
taskManager.registerTask("counter", 1000, []() {
static int count = 0;
Serial.printf("Count: %d\n", ++count);
});
// Lambda with capture
int threshold = 100;
taskManager.registerTask("monitor", 5000, [&threshold]() {
if (ESP.getFreeHeap() < threshold) {
Serial.println("Low memory warning!");
}
});
```
### Complex Task Registration
```cpp
class NetworkManager {
public:
void checkConnection() { /* ... */ }
void sendData(String data) { /* ... */ }
};
NetworkManager network;
// Multiple operations in one task
taskManager.registerTask("network_ops", 3000,
std::bind([](NetworkManager* net) {
net->checkConnection();
net->sendData("status_update");
}, &network));
```
## Task Control API
### Basic Operations
```cpp
// Enable/disable tasks
taskManager.enableTask("heartbeat");
taskManager.disableTask("maintenance");
// Change intervals
taskManager.setTaskInterval("heartbeat", 5000); // 5 seconds
// Check status
bool isRunning = taskManager.isTaskEnabled("heartbeat");
unsigned long interval = taskManager.getTaskInterval("heartbeat");
// Print all task statuses
taskManager.printTaskStatus();
```
### Task Lifecycle Management
```cpp
// Start/stop tasks
taskManager.startTask("heartbeat");
taskManager.stopTask("discovery");
// Bulk operations
taskManager.enableAllTasks();
taskManager.disableAllTasks();
```
## Task Configuration Options
When registering tasks, you can specify:
- **Name**: Unique identifier for the task
- **Interval**: Execution frequency in milliseconds
- **Callback**: Function, bound method, or lambda to execute
- **Enabled**: Whether the task starts enabled (default: true)
- **AutoStart**: Whether to start automatically (default: true)
```cpp
// Traditional function
taskManager.registerTask("delayed_task", 5000, taskFunction, true, false);
// Member function with std::bind
taskManager.registerTask("service_task", 3000,
std::bind(&Service::method, &instance), true, false);
// Lambda function
taskManager.registerTask("lambda_task", 2000,
[]() { Serial.println("Lambda!"); }, true, false);
```
## Adding Custom Tasks
### Method 1: Using std::bind (Recommended)
1. **Create your service class**:
```cpp
class SensorService {
public:
void readTemperature() {
// Read sensor logic
Serial.println("Reading temperature");
}
void calibrateSensors() {
// Calibration logic
Serial.println("Calibrating sensors");
}
};
```
2. **Register with TaskManager**:
```cpp
SensorService sensors;
taskManager.registerTask("temp_read", 1000,
std::bind(&SensorService::readTemperature, &sensors));
taskManager.registerTask("calibrate", 60000,
std::bind(&SensorService::calibrateSensors, &sensors));
```
### Method 2: Traditional Functions
1. **Define your task function**:
```cpp
void myCustomTask() {
// Your task logic here
Serial.println("Custom task executed");
}
```
2. **Register with TaskManager**:
```cpp
taskManager.registerTask("my_task", 10000, myCustomTask);
```
## Enhanced TaskManager Capabilities
### Task Status Monitoring
- **Real-time Status**: Check enabled/disabled state and running status
- **Performance Metrics**: Monitor execution intervals and timing
- **System Integration**: View task status alongside system resources
- **Bulk Operations**: Get status of all tasks at once
### Task Control Features
- **Runtime Control**: Enable/disable tasks without restart
- **Dynamic Intervals**: Change task execution frequency on-the-fly
- **Individual Status**: Get detailed information about specific tasks
- **Health Monitoring**: Track task health and system resources
## Remote Task Management
The TaskManager integrates with the API server to provide comprehensive remote task control and monitoring.
### Task Status Overview
Get a complete overview of all tasks and system status:
```bash
# Get comprehensive task status
curl http://192.168.1.100/api/tasks/status
```
**Response includes:**
- **Summary**: Total task count and active task count
- **Task Details**: Individual status for each task (name, interval, enabled, running, auto-start)
- **System Info**: Free heap memory and uptime
**Example Response:**
```json
{
"summary": {
"totalTasks": 6,
"activeTasks": 5
},
"tasks": [
{
"name": "discovery_send",
"interval": 1000,
"enabled": true,
"running": true,
"autoStart": true
},
{
"name": "heartbeat",
"interval": 2000,
"enabled": true,
"running": true,
"autoStart": true
}
],
"system": {
"freeHeap": 48748,
"uptime": 12345
}
}
```
### Individual Task Control
Control individual tasks with various actions:
```bash
# Control tasks
curl -X POST http://192.168.1.100/api/tasks/control \
-d "task=heartbeat&action=disable"
# Get detailed status for a specific task
curl -X POST http://192.168.1.100/api/tasks/control \
-d "task=discovery_send&action=status"
```
**Available Actions:**
- `enable` - Enable a task
- `disable` - Disable a task
- `start` - Start a task
- `stop` - Stop a task
- `status` - Get detailed status for a specific task
**Task Status Response:**
```json
{
"success": true,
"message": "Task status retrieved",
"task": "discovery_send",
"action": "status",
"taskDetails": {
"name": "discovery_send",
"enabled": true,
"running": true,
"interval": 1000,
"system": {
"freeHeap": 48748,
"uptime": 12345
}
}
}
```
## 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
## 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
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
## 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));
```
## 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
- New status monitoring methods are additive and don't break existing functionality
## Related Documentation
- **[TaskManager API Reference](./TaskManager.md)** - Detailed API documentation
- **[API Reference](./API.md)** - REST API for remote task management
- **[OpenAPI Specification](../api/)** - Machine-readable API specification