Prove Rust worker can receive archive tasks, manage queue, and call back to DataDaemon via Commands.execute().
┌──────────────────────────────────────┐
│ ArchiveDaemonServer (TypeScript) │
│ - Discovers @Archive entities │
│ - Monitors table sizes │
│ - Sends archive tasks to Rust │
│ - Health checks, reconnection │
└────────────┬─────────────────────────┘
│ Unix Socket
│ Message: { command: 'archive', collection, ... }
↓
┌──────────────────────────────────────┐
│ ArchiveWorker (Rust) │
│ - Unix socket server │
│ - FIFO task queue │
│ - Thread pool (process tasks) │
│ - IPC client to call Commands │
└────────────┬─────────────────────────┘
│ IPC (via socket back to TypeScript)
│ Commands.execute('data/list', {...})
↓
┌──────────────────────────────────────┐
│ DataDaemon (TypeScript) │
│ - Entity CRUD operations │
│ - Schema management │
└──────────────────────────────────────┘
TypeScript → Rust:
{
"command": "ping"
}Rust → TypeScript:
{
"status": "success",
"message": "pong"
}TypeScript → Rust (queue archive task):
{
"command": "archive",
"taskId": "task-001",
"collection": "chat_messages",
"sourceHandle": "primary",
"destHandle": "archive",
"maxRows": 10000,
"batchSize": 1000
}Rust → TypeScript (acknowledge):
{
"status": "queued",
"taskId": "task-001",
"queuePosition": 3
}Rust → TypeScript (execute data command):
{
"command": "execute",
"requestId": "req-001",
"targetCommand": "data/list",
"params": {
"collection": "chat_messages",
"dbHandle": "primary",
"limit": 1000,
"orderBy": [{"field": "createdAt", "direction": "asc"}]
}
}TypeScript → Rust (command result):
{
"requestId": "req-001",
"status": "success",
"result": {
"items": [...],
"count": 1000
}
}Rust → TypeScript (progress update):
{
"command": "progress",
"taskId": "task-001",
"archived": 500,
"total": 5000,
"status": "in_progress"
}Rust → TypeScript (task complete):
{
"command": "complete",
"taskId": "task-001",
"archived": 5000,
"duration": 1234,
"status": "success"
}-
daemons/archive-daemon/server/ArchiveWorkerClient.ts- Like LoggerWorkerClient
- Unix socket client
- Sends archive tasks to Rust
- Handles command execution callbacks from Rust
-
daemons/archive-daemon/server/ArchiveDaemonServer.ts(refactor)- Connect to Rust worker on start
- Queue tasks instead of synchronous execution
- Handle progress updates
- Health checks
-
shared/ipc/archive-worker/src/main.rs- Unix socket server
- Task queue (VecDeque)
- Thread pool for concurrent processing
- IPC client to call back to TypeScript
-
shared/ipc/archive-worker/src/queue.rs- FIFO task queue
- Task priority (optional)
-
shared/ipc/archive-worker/src/executor.rs- Execute archive tasks
- Call Commands.execute() via IPC
- Copy-verify-delete pattern
- TypeScript connects to Rust worker
- Send ping, receive pong
- Success: Connection established
- TypeScript queues 3 archive tasks
- Rust acknowledges and reports queue size
- Success: Queue working
- Rust calls Commands.execute('ping') via TypeScript
- TypeScript executes and returns result
- Success: Bidirectional communication working
- Queue task: archive 10 rows from chat_messages
- Rust calls data/list, data/create, data/delete via TypeScript
- TypeScript executes through DataDaemon
- Success: End-to-end archive working
- Queue 3 archive tasks (different collections)
- Rust processes concurrently (thread pool)
- Success: Concurrent processing working
- Investigate LoggerDaemon - Check if it actually works yet
- Create Rust skeleton - Basic socket server + echo messages
- Create TypeScript client - ArchiveWorkerClient connects to Rust
- Test connectivity - Ping/pong
- Add task queue - Queue tasks in Rust
- Add command callback - Rust calls Commands.execute() via TypeScript
- Implement simple archive - 10 rows only
- Add concurrency - Thread pool
- Full integration - Replace synchronous ArchiveDaemon logic
- Rust only knows: collection name, handle names, batch size
- DataDaemon handles serialization/deserialization
- Clean separation of concerns
- TypeScript → Rust: Archive tasks
- Rust → TypeScript: Command execution requests
- This is different from LoggerDaemon (one-way)
- Simple VecDeque
- No priority (for now)
- Process oldest task first
- Start with 3 threads (3 concurrent collections)
- Configurable based on system resources
- Like LoggerDaemon
- Ping every 30 seconds
- Auto-reconnect on failure
Skeleton is proven when:
- TypeScript can queue archive tasks to Rust
- Rust can call Commands.execute() back through TypeScript
- DataDaemon executes commands and returns results
- Rust successfully archives 10 rows from chat_messages
- No database thrashing (non-blocking)
-
Does LoggerDaemon actually work yet?
- Check if LoggerWorkerClient is implemented
- Test if Logger.ts actually routes to Rust
- Verify Unix socket communication works
-
How does Logger.ts call Rust?
- Same pattern for ArchiveWorker
- Reuse IPC client?
-
Command callback architecture?
- How does Rust call Commands.execute()?
- Same socket? Different socket?
- Request/response pattern?
Investigate LoggerDaemon - Verify it's a working reference implementation before modeling ArchiveWorker on it.