Retire-Cluster is a distributed system designed to repurpose idle devices into a unified computing cluster. The architecture follows a master-worker pattern with intelligent task scheduling and real-time monitoring.
┌─────────────────────────────────────────────────────────────┐
│ Main Node │
│ (NAS / Always-on Server) │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Core Components │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │ │
│ │ │Device Registry│ │Task Scheduler │ │Heartbeat │ │ │
│ │ │& Metadata │ │& Queue Mgmt │ │Monitor │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────┘ │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ Communication Layer │ │ │
│ │ │ - TCP Socket Server (Port 8080) │ │ │
│ │ │ - JSON Message Protocol │ │ │
│ │ │ - Connection Pool Management │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Web Dashboard │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │ │
│ │ │CLI Interface │ │Terminal UI │ │REST API │ │ │
│ │ │(xterm.js) │ │Renderer │ │Endpoints │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────┘ │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ Flask Web Server │ │ │
│ │ │ - Multi-format APIs (JSON/CSV/Text) │ │ │
│ │ │ - Server-Sent Events (SSE) │ │ │
│ │ │ - Real-time Streaming │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Data Persistence │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │ │
│ │ │SQLite │ │Configuration │ │Log Files │ │ │
│ │ │Database │ │JSON Files │ │Rotation │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────┘ │ │
│ └────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↕ TCP/JSON
Network Communication
↕ Heartbeat/Tasks
┌─────────────────────────────────────────────────────────────┐
│ Worker Nodes │
│ (Distributed Devices) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Android │ │ Old Laptop │ │ Raspberry Pi │ │
│ │ Device │ │ / Desktop │ │ / IoT │ │
│ │ │ │ │ │ │ │
│ │ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────────┐ │ │
│ │ │Termux │ │ │ │Linux/Win │ │ │ │Linux ARM │ │ │
│ │ │Python │ │ │ │Python │ │ │ │Python │ │ │
│ │ └──────────┘ │ │ └──────────┘ │ │ └──────────┘ │ │
│ │ │ │ │ │ │ │
│ │ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────────┐ │ │
│ │ │Device │ │ │ │System │ │ │ │Hardware │ │ │
│ │ │Profiler │ │ │ │Monitor │ │ │ │Interface │ │ │
│ │ └──────────┘ │ │ └──────────┘ │ │ └──────────┘ │ │
│ │ │ │ │ │ │ │
│ │ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────────┐ │ │
│ │ │Task │ │ │ │Task │ │ │ │Task │ │ │
│ │ │Executor │ │ │ │Executor │ │ │ │Executor │ │ │
│ │ └──────────┘ │ │ └──────────┘ │ │ └──────────┘ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
class DeviceRegistry:
def register_device(self, device_info: DeviceInfo) -> bool
def update_device_status(self, device_id: str, status: DeviceStatus)
def get_devices_by_capability(self, requirements: TaskRequirements) -> List[Device]
def mark_device_offline(self, device_id: str, reason: str)
class TaskScheduler:
def submit_task(self, task: Task) -> str # Returns task_id
def schedule_task(self, task: Task) -> Optional[Device]
def handle_task_completion(self, task_id: str, result: TaskResult)
def handle_device_failure(self, device_id: str)
class HeartbeatMonitor:
def process_heartbeat(self, device_id: str, metrics: SystemMetrics)
def check_device_timeouts(self) -> List[str] # Returns offline devices
def update_cluster_metrics(self)
class ClusterServer:
def start_server(self, host: str, port: int)
def handle_client_connection(self, client_socket: socket.socket)
def process_message(self, message: Message) -> Response
def broadcast_message(self, message: Message, target_devices: List[str])
/text/* - Plain text, CSV, TSV formats (AI-friendly)/api/v1/* - JSON APIs for programmatic access/stream/* - Server-Sent Events for real-time updates# Text API Examples
GET /text/devices # Pipe-delimited device list
GET /text/status # Key-value cluster status
GET /text/metrics # Prometheus format metrics
# JSON API Examples
GET /api/v1/devices # Structured device data
POST /api/v1/command # Execute CLI commands
GET /api/v1/cluster/status # Cluster information
# Streaming API Examples
GET /stream/devices # Real-time device updates
GET /stream/logs # Live log streaming
class DeviceProfiler:
def get_system_info(self) -> SystemInfo
def get_hardware_specs(self) -> HardwareSpecs
def detect_capabilities(self) -> List[Capability]
def get_performance_metrics(self) -> PerformanceMetrics
class TaskExecutor:
def execute_task(self, task: Task) -> TaskResult
def monitor_task_progress(self, task_id: str) -> ProgressReport
def cancel_task(self, task_id: str) -> bool
def cleanup_task_resources(self, task_id: str)
The system uses a JSON-based messaging protocol over TCP sockets:
{
"message_type": "register",
"sender_id": "device-001",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"device_info": {
"hostname": "android-phone",
"platform": "android",
"architecture": "aarch64",
"python_version": "3.11.0",
"role": "mobile"
},
"hardware_specs": {
"cpu_cores": 8,
"memory_total": 8589934592,
"disk_space": 128849018880,
"network_interfaces": ["wlan0"]
},
"capabilities": [
"computational",
"network_services",
"mobile_specific"
]
}
}
{
"message_type": "heartbeat",
"sender_id": "device-001",
"timestamp": "2024-01-15T10:31:00Z",
"data": {
"system_metrics": {
"cpu_usage": 25.5,
"memory_usage": 45.2,
"disk_usage": 12.8,
"load_average": [0.5, 0.3, 0.2],
"uptime": 86400
},
"status": "online",
"active_tasks": 2,
"last_activity": "2024-01-15T10:30:45Z"
}
}
{
"message_type": "task_assign",
"sender_id": "main-node",
"target_id": "device-001",
"timestamp": "2024-01-15T10:32:00Z",
"data": {
"task": {
"task_id": "task-abc123",
"task_type": "python_eval",
"priority": "normal",
"timeout": 300,
"payload": {
"expression": "sum(range(100000))",
"environment": {}
},
"requirements": {
"min_cpu_cores": 2,
"min_memory_gb": 1
}
}
}
}
{
"message_type": "task_result",
"sender_id": "device-001",
"timestamp": "2024-01-15T10:32:30Z",
"data": {
"task_id": "task-abc123",
"status": "completed",
"execution_time": 28.5,
"result": {
"output": "4999950000",
"exit_code": 0,
"metrics": {
"cpu_time": 25.2,
"memory_peak": 1048576
}
}
}
}
Worker Node Main Node
│ │
│──── TCP Connect ──────────►│
│◄─── Connection ACK ───────│
│ │
│──── Register Message ────►│
│ │ ┌─────────────────┐
│ │ │ Validate Device │
│ │ │ Store Metadata │
│ │ │ Update Registry │
│ │ └─────────────────┘
│◄─── Registration ACK ─────│
│ │
│──── Heartbeat Loop ──────►│
Main Node Worker Node
│ │
│ ┌─────────────────┐ │
│ │ Receive Task │ │
│ │ Match Device │ │
│ │ Check Resources │ │
│ └─────────────────┘ │
│ │
│──── Task Assignment ─────►│
│ │ ┌─────────────────┐
│ │ │ Validate Task │
│ │ │ Execute Safely │
│ │ │ Monitor Progress│
│ │ └─────────────────┘
│◄─── Task Progress ────────│
│◄─── Task Result ──────────│
│ │
│ ┌─────────────────┐ │
│ │ Process Result │ │
│ │ Update Status │ │
│ │ Notify Client │ │
│ └─────────────────┘ │
Worker Nodes Main Node Web Dashboard
│ │ │
│──── Heartbeats ─────►│ │
│ │ ┌─────────────────┐ │
│ │ │ Aggregate │ │
│ │ │ Metrics │ │
│ │ │ Update Status │ │
│ │ └─────────────────┘ │
│ │ │
│ │◄─── API Requests ────│
│ │──── SSE Events ─────►│
│ │──── JSON/Text Data ──►│
┌─────────────────────────────────┐
│ Development Host │
│ │
│ ┌───────────┐ ┌─────────────┐ │
│ │Main Node │ │Worker Node │ │
│ │(Terminal1)│ │(Terminal2) │ │
│ └───────────┘ └─────────────┘ │
│ │
│ ┌─────────────────────────────┐ │
│ │ Web Dashboard │ │
│ │ (Terminal3/Browser) │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────┘
┌─────────────────────┐ ┌──────────────────┐
│ NAS Server │ │ Old Laptop │
│ │ │ │
│ ┌─────────────────┐ │ │ ┌──────────────┐ │
│ │ Main Node │ │ │ │ Worker Node │ │
│ │ (Docker) │ │◄───────►│ │ (Native) │ │
│ └─────────────────┘ │ │ └──────────────┘ │
│ │ └──────────────────┘
│ ┌─────────────────┐ │
│ │ Web Dashboard │ │ ┌──────────────────┐
│ │ (Docker) │ │ │ Android Phone │
│ └─────────────────┘ │ │ │
└─────────────────────┘ │ ┌──────────────┐ │
│ │ Worker Node │ │
┌─────────────────────┐ │ │ (Termux) │ │
│ Raspberry Pi │ │ └──────────────┘ │
│ │ └──────────────────┘
│ ┌─────────────────┐ │
│ │ Worker Node │ │ ┌──────────────────┐
│ │ (Native) │ │ │ Another Device │
│ └─────────────────┘ │ │ │
└─────────────────────┘ │ ┌──────────────┐ │
│ │ Worker Node │ │
│ │ (Native) │ │
│ └──────────────┘ │
└──────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ NAS Server │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Docker Environment │ │
│ │ │ │
│ │ ┌──────────────────────┐ ┌──────────────────┐ │ │
│ │ │ retire-cluster │ │ nginx │ │ │
│ │ │ main-node │ │ reverse-proxy │ │ │
│ │ │ │ │ (optional) │ │ │
│ │ │ ┌──────────────────┐ │ │ │ │ │
│ │ │ │ Main Node │ │ │ │ │ │
│ │ │ │ (Port 8080) │ │ │ │ │ │
│ │ │ └──────────────────┘ │ │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ ┌──────────────────┐ │ │ │ │ │
│ │ │ │ Web Dashboard │ │ │ │ │ │
│ │ │ │ (Port 5000) │ │ │ │ │ │
│ │ │ └──────────────────┘ │ │ │ │ │
│ │ └──────────────────────┘ └──────────────────┘ │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Persistent Volumes │ │
│ │ /volume1/docker/retire-cluster/ │ │
│ │ ├── config/ (Configuration files) │ │
│ │ ├── database/ (SQLite database) │ │
│ │ └── logs/ (Application logs) │ │
│ └────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
This architecture provides a solid foundation for the Retire-Cluster system while maintaining flexibility for future enhancements and scalability requirements.