Kit de herramientas componible para la supervisión de servicios en Rust
Malkuth ayuda a los programas automatizados y de larga duración a hacer cuatro cosas difíciles:
- Transporte conectable — JSON-RPC sobre bucle de retorno TCP local, WebSocket remoto o IPC local (sockets Unix / tuberías con nombre vía
interprocess). Un único traitTransport, despachado según el esquema de URL. - Trabajadores supervisados — lanzar un proceso, monitorizar su salud, reiniciarlo en caso de fallo, drenar conexiones antes de apagar.
- Facilidades opcionales y conectables mediante hooks — la fuente de salida, las sondas, los hooks de latido y de drenaje son traits. Usa los predeterminados (señal de salida del SO, sondas axum, workers supervisados) o proporciona los tuyos (p. ej. activar el drenaje desde un comando "stop" en banda que reciba tu servidor). Un orquestador
Supervised«con pilas incluidas» los conecta entre sí. - Un CLI watchdog —
malkuth -- <cmd>envuelve un programa con observación de archivos, un pool de pods y un proxy inverso persistente de capa 4.
malkuth [--watch PATH]... [--proxy PUBLIC:LO-HI] [--pod-count N] -- <cmd> [args...]
Ejecuta 5 copias paralelas de tu servidor (cada una escuchando en la variable de entorno PORT → se autoasignan 3001–3005), frente a un proxy persistente en el puerto 3000:
malkuth --watch ./src --watch ./res \
--proxy 3000:3000-3999 --pod-count 5 \
-- cargo runEl proxy enruta cada IP de cliente a un backend fijo mediante hashing consistente, de modo que un cliente siga alcanzando el mismo pod hasta que ese pod se reinicie o se reduzca la escala — la base para lanzamientos graduales / reinicios progresivos. Ante un cambio de archivo, drena y reinicia un pod a la vez.
[dependencies]
malkuth = "0.1"
# features: tcp (default) | ws | ipc | signals (default) | worker | probes |
# file-lock | lease | pg-lock | replica | leader-follower | schema | cliuse std::sync::Arc;
use malkuth::{Client, Router, Server, Supervised, Transport};
use malkuth::transport::TcpTransport;
use serde_json::json;
#[tokio::main]
async fn main() -> std::io::Result<()> {
// Bind once; build a router with the standard lifecycle RPC + your methods.
let lis = TcpTransport.listen("tcp://127.0.0.1:0").await?;
let supervised = Supervised::new().signals(); // OS-signal exit source
let ctrl = supervised.drain_controller();
let handler = Arc::new(
Router::new()
.lifecycle(ctrl, None) // Lifecycle.Drain/Status/...
.route("ping", |_| Box::pin(async { Ok(json!("pong")) })),
);
// Race the server against the exit source, then run drain hooks.
supervised.serve_rpc_listener(lis, handler).await
}¿Necesitas que el drenaje se active por tu propia lógica en lugar de por señales? Implementa
malkuth::ExitSource y pásalo mediante .exit(...). ¿Quieres coordinación respaldada por Postgres?
La funcionalidad pg-lock proporciona un backend CoordinationLock.
| Funcionalidad | Habilita |
|---|---|
tcp (default) |
JSON-RPC sobre TCP local/remoto (tokio::net) |
ws |
JSON-RPC sobre WebSocket (tokio-tungstenite) |
ipc |
JSON-RPC sobre IPC local (interprocess) |
signals (default) |
ExitSource por defecto basado en señales del SO (tokio::signal) |
worker |
Workers supervisados como procesos hijos (tokio::process) |
probes |
Router axum /healthz + /readyz |
file-lock |
Backend CoordinationLock con flock POSIX (unix) |
lease |
CoordinationLock con arrendamiento de archivo y expiración automática por TTL (seguro ante fallos) |
pg-lock |
Backend pg_advisory_lock de PostgreSQL (tokio-postgres) |
replica |
InstanceRegistry en memoria |
leader-follower |
LeaseLeaderElector (sobre el backend de arrendamiento) |
schema |
Derivaciones schemars::JsonSchema para los tipos de cable |
cli |
El binario watchdog malkuth (pool de pods + proxy persistente) |
Las capas 1–3 (ciclo de vida/drenaje, sondas, transferencia de escucha) y el núcleo JSON-RPC
(codec + servidor/cliente + transportes tcp/ws/ipc) están implementados y probados
de extremo a extremo. El pool de pods del CLI + proxy persistente está funcionando (verificado e2e). Los tres backends CoordinationLock (file-lock, lease, pg-lock) y el LeaseLeaderElector de leader-follower están implementados. Consulta
docs/design/ para el diseño.
Construye malkuth con la feature mcp y ejecuta el servidor stdio — expone el toolkit de supervisión a los asistentes de codificación de IA a través del Model Context Protocol:
malkuth mcpEl servidor anuncia dos herramientas: malkuth_supervise (lanza un conjunto de workers bajo el supervisor con políticas de reinicio + un limitador de tasa de ventana deslizante; se bloquea hasta que terminan o se dispara el timeout, luego devuelve la instantánea de estado final) y malkuth_probe (comprobación HTTP healthz / readyz contra una URL de servicio). Conéctalo a un cliente MCP:
{
"mcpServers": {
"malkuth": { "command": "malkuth", "args": ["mcp"] }
}
}La feature mcp implica worker + schema; añade rmcp y un cliente reqwest para la herramienta de sonda.
SySL-1.0 (Synthetic Source License). Consulte LICENSE.
Para despliegues MCP en producción, use un envoltorio de reinicio automático para mantener el servidor activo durante las actualizaciones sin interrumpir la sesión del cliente.
#!/bin/bash while true; do /path/to/malkuth mcp sleep 0.2 done
- El envoltorio ejecuta
malkuth mcpen un buclewhile true. - Si el proceso sale, se reinicia en menos de 0,2 segundos.
- Para actualizar:
kill $(pgrep -f "malkuth mcp" | head -1) - malkuth también puede supervisar otras herramientas MCP — utilícelo como vigilante para toda la cadena de herramientas MCP.
