Increase the time before auto shutdown of dev server (vibe-kanban 8b5175a7)

Increase from 60s to 120s, allow to be overriden with CLI
This commit is contained in:
Louis Knight-Webb
2025-11-05 11:48:41 +00:00
parent bb7562b47c
commit 54909d4215
4 changed files with 14 additions and 12 deletions

View File

@@ -1,6 +1,6 @@
# MCP Dev Server Manager
A daemon that accepts requests from MCP clients to start dev servers, allocating unique ports to avoid collisions and shutting down idle connections after 60s of inactivity.
A daemon that accepts requests from MCP clients to start dev servers, allocating unique ports to avoid collisions and shutting down idle connections after 120s of inactivity.
## Example
@@ -16,7 +16,7 @@ A daemon that accepts requests from MCP clients to start dev servers, allocating
- **Avoid port collisions**: when working with websites, it's often necessary to specify different ports if you want to run multiple dev servers
- **Automatic port allocation** starting at 3010 with reuse
- **Log capture** with 512KB ring buffers per server
- **Auto-cleanup** of idle sessions after 60 seconds
- **Auto-cleanup** of idle sessions after 120 seconds (configurable via `--idle-timeout`)
## Installation & Usage
@@ -129,7 +129,7 @@ Get stdout/stderr logs for a development server session.
- Single `Arc<Manager>` shared across all client connections
- Each connection gets a fresh `DevManagerService` instance
- Mutex-protected HashMap for session storage
- Background sweeper runs every 5 seconds to clean up idle sessions (>60s)
- Background sweeper runs every 5 seconds to clean up idle sessions (>120s by default)
### Session Keys

View File

@@ -16,6 +16,7 @@ use serde_json::Value;
use service::DevManagerService;
use std::net::{Ipv4Addr, SocketAddr};
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::mpsc;
fn inject_cwd_if_start_tool(
@@ -48,8 +49,8 @@ fn inject_cwd_if_start_tool(
msg
}
pub async fn run_daemon(port: u16) -> Result<()> {
let manager = Arc::new(Manager::new());
pub async fn run_daemon(port: u16, idle_timeout_secs: u64) -> Result<()> {
let manager = Arc::new(Manager::new(Duration::from_secs(idle_timeout_secs)));
let bind = SocketAddr::from((Ipv4Addr::LOCALHOST, port));
println!("MCP daemon listening on {}", bind);

View File

@@ -14,6 +14,8 @@ enum Command {
Daemon {
#[arg(long, env = "PORT", default_value_t = 3009)]
port: u16,
#[arg(long, env = "MCP_IDLE_TIMEOUT", default_value_t = 120)]
idle_timeout: u64,
},
#[command(about = "Run as STDIO proxy that connects to daemon")]
Stdio {
@@ -30,8 +32,8 @@ enum Command {
async fn main() -> anyhow::Result<()> {
let cli = Cli::parse();
match cli.command.unwrap_or(Command::Daemon { port: 3009 }) {
Command::Daemon { port } => dev_manager_mcp::run_daemon(port).await,
match cli.command.unwrap_or(Command::Daemon { port: 3009, idle_timeout: 120 }) {
Command::Daemon { port, idle_timeout } => dev_manager_mcp::run_daemon(port, idle_timeout).await,
Command::Stdio { daemon_url } => dev_manager_mcp::run_stdio_proxy(&daemon_url).await,
}
}

View File

@@ -10,7 +10,6 @@ use tokio::process::Command;
type SessionKey = String;
const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
const RUNNING_IDLE_SECS: u64 = 60;
const EXITED_RETENTION_SECS: u64 = 600;
fn generate_session_key() -> String {
@@ -31,7 +30,7 @@ pub struct Manager {
}
impl Manager {
pub fn new() -> Self {
pub fn new(idle_timeout: Duration) -> Self {
let manager = Self {
inner: Arc::new(Mutex::new(ManagerInner {
servers: HashMap::new(),
@@ -39,11 +38,11 @@ impl Manager {
})),
};
manager.start_sweeper();
manager.start_sweeper(idle_timeout);
manager
}
fn start_sweeper(&self) {
fn start_sweeper(&self, idle_timeout: Duration) {
let inner = self.inner.clone();
tokio::spawn(async move {
let mut interval = tokio::time::interval(Duration::from_secs(5));
@@ -57,7 +56,7 @@ impl Manager {
};
let now = Instant::now();
let idle_threshold = Duration::from_secs(RUNNING_IDLE_SECS);
let idle_threshold = idle_timeout;
let retention_threshold = Duration::from_secs(EXITED_RETENTION_SECS);
let mut to_stop = Vec::new();