diff --git a/Cargo.lock b/Cargo.lock index d0d1fe3e1d0f..f90fda9a6b31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4354,6 +4354,7 @@ dependencies = [ "anyhow", "async-trait", "cargo-lock", + "chrono", "file-rotate", "ignore", "kdam", diff --git a/crates/tabby-scheduler/Cargo.toml b/crates/tabby-scheduler/Cargo.toml index 3170a65be534..9809dd0f47ac 100644 --- a/crates/tabby-scheduler/Cargo.toml +++ b/crates/tabby-scheduler/Cargo.toml @@ -29,6 +29,7 @@ serdeconv.workspace = true cargo-lock = { version = "9.0.0", features = ["dependency-tree"] } tokio-cron-scheduler = { workspace = true } tokio = { workspace = true, features = ["process"] } +chrono.workspace = true [dev-dependencies] temp_testdir = "0.2" diff --git a/crates/tabby-scheduler/src/lib.rs b/crates/tabby-scheduler/src/lib.rs index 1987dd2fb3de..c76ca0649569 100644 --- a/crates/tabby-scheduler/src/lib.rs +++ b/crates/tabby-scheduler/src/lib.rs @@ -31,7 +31,7 @@ pub async fn scheduler( // Every 10 minutes scheduler .add(Job::new_async( - "* 1/10 * * * * *", + "0 1/10 * * * *", move |uuid, mut scheduler| { let access = access.clone(); let args = args.clone(); @@ -92,7 +92,10 @@ pub async fn scheduler( } if let Ok(Some(next_tick)) = scheduler.next_tick_for_job(uuid).await { - info!("Next time for scheduler job is {:?}", next_tick); + info!( + "Next time for scheduler job is {:?}", + next_tick.with_timezone(&chrono::Local) + ); } }) }, diff --git a/crates/tabby/src/serve.rs b/crates/tabby/src/serve.rs index 286c0c9d232c..b1759abbb18b 100644 --- a/crates/tabby/src/serve.rs +++ b/crates/tabby/src/serve.rs @@ -125,7 +125,8 @@ pub async fn main(config: &Config, args: &ServeArgs) { #[cfg(feature = "ee")] let (api, ui) = if args.webserver { let (api, ui) = - tabby_webserver::public::attach_webserver(api, ui, logger, code, config).await; + tabby_webserver::public::attach_webserver(api, ui, logger, code, config, args.port) + .await; (api, ui) } else { let ui = ui.fallback(|| async { axum::response::Redirect::temporary("/swagger-ui") }); diff --git a/ee/tabby-webserver/Cargo.toml b/ee/tabby-webserver/Cargo.toml index eed30240fbec..29201d9b30b5 100644 --- a/ee/tabby-webserver/Cargo.toml +++ b/ee/tabby-webserver/Cargo.toml @@ -33,7 +33,7 @@ tabby-common = { path = "../../crates/tabby-common" } tabby-db = { path = "../../ee/tabby-db" } tarpc = { version = "0.33.0", features = ["serde-transport"] } thiserror.workspace = true -tokio = { workspace = true, features = ["fs"] } +tokio = { workspace = true, features = ["fs", "process"] } tokio-cron-scheduler = { workspace = true } tokio-tungstenite = "0.20.1" tower = { version = "0.4", features = ["util"] } diff --git a/ee/tabby-webserver/src/handler.rs b/ee/tabby-webserver/src/handler.rs index 42c430b190db..c5800dbc68a9 100644 --- a/ee/tabby-webserver/src/handler.rs +++ b/ee/tabby-webserver/src/handler.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use std::{process::Stdio, sync::Arc}; use axum::{ extract::State, @@ -27,6 +27,7 @@ pub async fn attach_webserver( logger: Arc, code: Arc, config: &Config, + local_port: u16, ) -> (Router, Router) { let repository_cache = Arc::new(RepositoryCache::new_initialized( config.repositories.clone(), @@ -58,6 +59,17 @@ pub async fn attach_webserver( .route("/graphiql", routing::get(graphiql("/graphql", None))) .fallback(ui::handler); + tokio::spawn(async move { + loop { + // Give some time for server being ready. + tokio::time::sleep(std::time::Duration::from_secs(10)).await; + start_scheduler_job( + local_port, + ctx.worker().read_registration_token().await.unwrap(), + ) + .await; + } + }); (api, ui) } @@ -68,3 +80,20 @@ async fn distributed_tabby_layer( ) -> axum::response::Response { ws.worker().dispatch_request(request, next).await } + +async fn start_scheduler_job(local_port: u16, registeration_token: String) { + let exe = std::env::current_exe().unwrap(); + let mut child = tokio::process::Command::new(exe) + .arg("scheduler") + .arg("--url") + .arg(format!("localhost:{local_port}")) + .arg("--token") + .arg(registeration_token) + .stdin(Stdio::null()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .kill_on_drop(true) + .spawn() + .unwrap(); + let _ = child.wait().await; +}