diff --git a/Cargo.lock b/Cargo.lock index bfa44b22..28d77aa1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -478,7 +478,7 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "c0mpute-api" -version = "0.2.69" +version = "0.2.70" dependencies = [ "anyhow", "c0mpute-proto", @@ -493,7 +493,7 @@ dependencies = [ [[package]] name = "c0mpute-bench" -version = "0.2.69" +version = "0.2.70" dependencies = [ "anyhow", "blake3", @@ -504,7 +504,7 @@ dependencies = [ [[package]] name = "c0mpute-cli" -version = "0.2.69" +version = "0.2.70" dependencies = [ "anyhow", "axum", @@ -534,7 +534,7 @@ dependencies = [ [[package]] name = "c0mpute-core" -version = "0.2.69" +version = "0.2.70" dependencies = [ "aes-gcm", "anyhow", @@ -578,7 +578,7 @@ dependencies = [ [[package]] name = "c0mpute-doctor" -version = "0.2.69" +version = "0.2.70" dependencies = [ "anyhow", "serde", @@ -590,7 +590,7 @@ dependencies = [ [[package]] name = "c0mpute-envelope" -version = "0.2.69" +version = "0.2.70" dependencies = [ "blake3", "bs58", @@ -603,7 +603,7 @@ dependencies = [ [[package]] name = "c0mpute-gateway" -version = "0.2.69" +version = "0.2.70" dependencies = [ "anyhow", "axum", @@ -625,7 +625,7 @@ dependencies = [ [[package]] name = "c0mpute-market" -version = "0.2.69" +version = "0.2.70" dependencies = [ "c0mpute-envelope", "serde", @@ -635,7 +635,7 @@ dependencies = [ [[package]] name = "c0mpute-net" -version = "0.2.69" +version = "0.2.70" dependencies = [ "anyhow", "async-trait", @@ -652,7 +652,7 @@ dependencies = [ [[package]] name = "c0mpute-placement" -version = "0.2.69" +version = "0.2.70" dependencies = [ "anyhow", "async-trait", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "c0mpute-proto" -version = "0.2.69" +version = "0.2.70" dependencies = [ "blake3", "hex", @@ -685,7 +685,7 @@ dependencies = [ [[package]] name = "c0mpute-secure-chat" -version = "0.2.69" +version = "0.2.70" dependencies = [ "aes-gcm", "anyhow", @@ -708,7 +708,7 @@ dependencies = [ [[package]] name = "c0mpute-store" -version = "0.2.69" +version = "0.2.70" dependencies = [ "anyhow", "blake3", @@ -726,7 +726,7 @@ dependencies = [ [[package]] name = "c0mpute-transcode" -version = "0.2.69" +version = "0.2.70" dependencies = [ "anyhow", "c0mpute-proto", @@ -739,7 +739,7 @@ dependencies = [ [[package]] name = "c0mpute-update" -version = "0.2.69" +version = "0.2.70" dependencies = [ "anyhow", "hex", @@ -753,7 +753,7 @@ dependencies = [ [[package]] name = "c0mpute-verify" -version = "0.2.69" +version = "0.2.70" dependencies = [ "anyhow", "blake3", diff --git a/Cargo.toml b/Cargo.toml index ad2f4b8b..351c4881 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ members = [ ] [workspace.package] -version = "0.2.69" +version = "0.2.70" edition = "2024" license = "MIT" repository = "https://github.com/profullstack/c0mpute" diff --git a/apps/tui/package.json b/apps/tui/package.json index 20af29f9..d1811219 100644 --- a/apps/tui/package.json +++ b/apps/tui/package.json @@ -1,6 +1,6 @@ { "name": "@c0mpute/tui", - "version": "0.2.69", + "version": "0.2.70", "private": true, "type": "module", "bin": { diff --git a/apps/web/package.json b/apps/web/package.json index d6f0c692..5125e622 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "c0mpute", - "version": "0.2.69", + "version": "0.2.70", "private": true, "type": "module", "scripts": { diff --git a/apps/web/src/app/releases/latest.json/route.ts b/apps/web/src/app/releases/latest.json/route.ts index e3cf4e21..022faa53 100644 --- a/apps/web/src/app/releases/latest.json/route.ts +++ b/apps/web/src/app/releases/latest.json/route.ts @@ -28,7 +28,7 @@ export const dynamic = "force-dynamic"; * this in sync with the workspace version in `Cargo.toml` on each release so a * freshly built CLI reports "already latest" rather than a phantom upgrade. */ -const FALLBACK_VERSION = "0.2.69"; +const FALLBACK_VERSION = "0.2.70"; const FALLBACK_MIN_REQUIRED = "0.0.1"; type Channel = "stable" | "beta" | "nightly"; diff --git a/node/crates/c0mpute-core/src/diffusion.rs b/node/crates/c0mpute-core/src/diffusion.rs index b79bd88d..30a7849f 100644 --- a/node/crates/c0mpute-core/src/diffusion.rs +++ b/node/crates/c0mpute-core/src/diffusion.rs @@ -156,6 +156,26 @@ pub fn can_serve(config: &crate::config::DiffusionConfig) -> bool { && installed() && fast_enough(config) && has_headroom_with(config, memory()) + && idle_enough_with(load_avg_1m(), logical_cpus()) + && node_slot().available_permits() > 0 +} + +/// Busiest a box may be (1-minute load average per logical CPU) and still +/// take a render. A render needs half the box for ~2 minutes; on a box +/// already this busy it takes 10+ and the buyer is better told "no worker". +pub const MAX_LOAD_PER_CPU: f64 = 0.75; + +/// Pure decision: is the box idle enough to start an image now? +pub fn idle_enough_with(load_1m: f64, cpus: usize) -> bool { + cpus > 0 && load_1m.is_finite() && load_1m < cpus as f64 * MAX_LOAD_PER_CPU +} + +fn load_avg_1m() -> f64 { + sysinfo::System::load_average().one +} + +fn logical_cpus() -> usize { + std::thread::available_parallelism().map(|n| n.get()).unwrap_or(1) } fn now_secs() -> u64 { @@ -708,6 +728,15 @@ mod tests { assert_eq!(parse_stat("garbage"), None); } + #[test] + fn a_busy_box_does_not_take_images() { + assert!(idle_enough_with(4.0, 16)); + assert!(!idle_enough_with(26.5, 16), "seed2 at load 26 on 16 vCPUs"); + assert!(!idle_enough_with(12.0, 16), "75% is the line"); + assert!(!idle_enough_with(f64::NAN, 16)); + assert!(!idle_enough_with(0.0, 0)); + } + #[test] fn png_magic_is_checked() { assert!(is_png(b"\x89PNG\r\n\x1a\n0000")); diff --git a/package.json b/package.json index 39a45243..ec48caae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "c0mpute-monorepo", - "version": "0.2.69", + "version": "0.2.70", "private": true, "workspaces": [ "apps/*", diff --git a/packages/shared/package.json b/packages/shared/package.json index 8b7d7451..2bf0ee27 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@c0mpute/shared", - "version": "0.2.69", + "version": "0.2.70", "private": true, "type": "module", "main": "./dist/index.js", diff --git a/plugins/ad-generator-agent/module.toml b/plugins/ad-generator-agent/module.toml index b787771e..1e19a15e 100644 --- a/plugins/ad-generator-agent/module.toml +++ b/plugins/ad-generator-agent/module.toml @@ -21,7 +21,7 @@ [module] id = "ad-generator-agent" name = "Ad Generator Agent — every ad type from one URL" -version = "0.2.69" +version = "0.2.70" kind = "service" category = "applications" status = "available" diff --git a/plugins/ads-manager/module.toml b/plugins/ads-manager/module.toml index 58c8f925..b9d39516 100644 --- a/plugins/ads-manager/module.toml +++ b/plugins/ads-manager/module.toml @@ -18,7 +18,7 @@ [module] id = "ads-manager" name = "Ads Manager — shared ad operations layer" -version = "0.2.69" +version = "0.2.70" kind = "service" category = "applications" status = "coming-soon" diff --git a/plugins/coinpay/module.toml b/plugins/coinpay/module.toml index 022a2427..215628d5 100644 --- a/plugins/coinpay/module.toml +++ b/plugins/coinpay/module.toml @@ -7,7 +7,7 @@ [module] id = "coinpay" name = "CoinPay — DID, payments, escrow, reputation" -version = "0.2.69" +version = "0.2.70" kind = "service" category = "applications" status = "available" diff --git a/plugins/crawl/module.toml b/plugins/crawl/module.toml index e8fcda29..d969ebcd 100644 --- a/plugins/crawl/module.toml +++ b/plugins/crawl/module.toml @@ -8,7 +8,7 @@ [module] id = "crawl" name = "Crawl — distributed web fetching" -version = "0.2.69" +version = "0.2.70" kind = "workload" category = "data" status = "available" diff --git a/plugins/ctv-ads/module.toml b/plugins/ctv-ads/module.toml index 8adc3ef5..e2cf1816 100644 --- a/plugins/ctv-ads/module.toml +++ b/plugins/ctv-ads/module.toml @@ -20,7 +20,7 @@ [module] id = "ctv-ads" name = "CTV Ads — Connected TV ad marketplace" -version = "0.2.69" +version = "0.2.70" kind = "service" category = "applications" status = "coming-soon" diff --git a/plugins/diffusion/module.toml b/plugins/diffusion/module.toml index 9bc71ff5..f6adeca4 100644 --- a/plugins/diffusion/module.toml +++ b/plugins/diffusion/module.toml @@ -11,7 +11,7 @@ [module] id = "diffusion" name = "Diffusion — image generation" -version = "0.2.69" +version = "0.2.70" kind = "workload" category = "ai" status = "available" diff --git a/plugins/embed/module.toml b/plugins/embed/module.toml index ec5dda8d..f290de42 100644 --- a/plugins/embed/module.toml +++ b/plugins/embed/module.toml @@ -13,7 +13,7 @@ [module] id = "embed" name = "Embeddings — vector generation" -version = "0.2.69" +version = "0.2.70" kind = "workload" category = "ai" status = "coming-soon" diff --git a/plugins/gameserver/module.toml b/plugins/gameserver/module.toml index 18ee8ad2..0c6cffcf 100644 --- a/plugins/gameserver/module.toml +++ b/plugins/gameserver/module.toml @@ -14,7 +14,7 @@ [module] id = "gameserver" name = "Game server — Minecraft / Factorio / Valheim" -version = "0.2.69" +version = "0.2.70" kind = "workload" category = "infrastructure" status = "coming-soon" diff --git a/plugins/hosting/module.toml b/plugins/hosting/module.toml index 074393d1..a9c7fb30 100644 --- a/plugins/hosting/module.toml +++ b/plugins/hosting/module.toml @@ -12,7 +12,7 @@ [module] id = "hosting" name = "Hosting — censorship-resistant static sites" -version = "0.2.69" +version = "0.2.70" kind = "workload" category = "data" status = "coming-soon" diff --git a/plugins/infernet/module.toml b/plugins/infernet/module.toml index cccb287a..59bda752 100644 --- a/plugins/infernet/module.toml +++ b/plugins/infernet/module.toml @@ -10,7 +10,7 @@ [module] id = "infernet" name = "Infernet Protocol — AI inference" -version = "0.2.69" +version = "0.2.70" kind = "workload" category = "ai" status = "partial" diff --git a/plugins/live-stream/module.toml b/plugins/live-stream/module.toml index a8e9b4bf..3a1d3cf2 100644 --- a/plugins/live-stream/module.toml +++ b/plugins/live-stream/module.toml @@ -23,7 +23,7 @@ [module] id = "live-stream" name = "Live Stream — p2p HLS live streaming" -version = "0.2.69" +version = "0.2.70" kind = "service" category = "media" status = "coming-soon" diff --git a/plugins/ocr/module.toml b/plugins/ocr/module.toml index 7814667f..daf12861 100644 --- a/plugins/ocr/module.toml +++ b/plugins/ocr/module.toml @@ -12,7 +12,7 @@ [module] id = "ocr" name = "OCR — document text extraction" -version = "0.2.69" +version = "0.2.70" kind = "workload" category = "ai" status = "coming-soon" diff --git a/plugins/podcast-ads/module.toml b/plugins/podcast-ads/module.toml index bfd4bec1..ef07118b 100644 --- a/plugins/podcast-ads/module.toml +++ b/plugins/podcast-ads/module.toml @@ -22,7 +22,7 @@ [module] id = "podcast-ads" name = "Podcast Ads — audio ad marketplace" -version = "0.2.69" +version = "0.2.70" kind = "service" category = "applications" status = "coming-soon" diff --git a/plugins/podcasting/module.toml b/plugins/podcasting/module.toml index 3e46a93b..4353052d 100644 --- a/plugins/podcasting/module.toml +++ b/plugins/podcasting/module.toml @@ -20,7 +20,7 @@ [module] id = "podcasting" name = "Podcasting — p2p podcast publishing" -version = "0.2.69" +version = "0.2.70" kind = "service" category = "media" status = "coming-soon" diff --git a/plugins/podcasts/module.toml b/plugins/podcasts/module.toml index 8f313be3..9bfa3fee 100644 --- a/plugins/podcasts/module.toml +++ b/plugins/podcasts/module.toml @@ -19,7 +19,7 @@ [module] id = "podcasts" name = "Podcasts — p2p podcast listener" -version = "0.2.69" +version = "0.2.70" kind = "service" category = "media" status = "coming-soon" diff --git a/plugins/render/module.toml b/plugins/render/module.toml index f84386b7..4aa247d2 100644 --- a/plugins/render/module.toml +++ b/plugins/render/module.toml @@ -13,7 +13,7 @@ [module] id = "render" name = "Render — Blender 3D rendering" -version = "0.2.69" +version = "0.2.70" kind = "workload" category = "media" status = "coming-soon" diff --git a/plugins/secure-chat/module.toml b/plugins/secure-chat/module.toml index aa0df69a..e732fbaf 100644 --- a/plugins/secure-chat/module.toml +++ b/plugins/secure-chat/module.toml @@ -18,7 +18,7 @@ [module] id = "secure-chat" name = "Secure Chat — E2E encrypted p2p messaging" -version = "0.2.69" +version = "0.2.70" kind = "service" category = "applications" status = "partial" diff --git a/plugins/storage/module.toml b/plugins/storage/module.toml index 22c86d22..f2b29942 100644 --- a/plugins/storage/module.toml +++ b/plugins/storage/module.toml @@ -20,7 +20,7 @@ [module] id = "storage" name = "Storage — Reed-Solomon shard service" -version = "0.2.69" +version = "0.2.70" kind = "service" category = "data" status = "available" diff --git a/plugins/train/module.toml b/plugins/train/module.toml index 19b4517e..3ad1558d 100644 --- a/plugins/train/module.toml +++ b/plugins/train/module.toml @@ -13,7 +13,7 @@ [module] id = "train" name = "Fine-tune — LoRA/QLoRA training" -version = "0.2.69" +version = "0.2.70" kind = "workload" category = "ai" status = "coming-soon" diff --git a/plugins/transcode/module.toml b/plugins/transcode/module.toml index 23c4e00e..29c02bba 100644 --- a/plugins/transcode/module.toml +++ b/plugins/transcode/module.toml @@ -7,7 +7,7 @@ [module] id = "transcode" name = "FFmpeg Transcoding" -version = "0.2.69" +version = "0.2.70" kind = "workload" category = "media" status = "available" diff --git a/plugins/tts/module.toml b/plugins/tts/module.toml index 34de01f4..67cbf8ec 100644 --- a/plugins/tts/module.toml +++ b/plugins/tts/module.toml @@ -15,7 +15,7 @@ [module] id = "tts" name = "TTS — text-to-speech" -version = "0.2.69" +version = "0.2.70" kind = "workload" category = "ai" status = "available" diff --git a/plugins/video/module.toml b/plugins/video/module.toml index 89a03a1e..7ef2321a 100644 --- a/plugins/video/module.toml +++ b/plugins/video/module.toml @@ -44,7 +44,7 @@ [module] id = "video" name = "Video — generation (Wan 2.2, LTX-2.3 with audio)" -version = "0.2.69" +version = "0.2.70" kind = "workload" category = "ai" status = "partial" diff --git a/plugins/webhook/module.toml b/plugins/webhook/module.toml index 86f54d66..b630204f 100644 --- a/plugins/webhook/module.toml +++ b/plugins/webhook/module.toml @@ -7,7 +7,7 @@ [module] id = "webhook" name = "Webhooks — paid, end-to-end encrypted delivery" -version = "0.2.69" +version = "0.2.70" kind = "workload" category = "infrastructure" status = "available" diff --git a/plugins/whisper/module.toml b/plugins/whisper/module.toml index 3dc34928..fb968530 100644 --- a/plugins/whisper/module.toml +++ b/plugins/whisper/module.toml @@ -7,7 +7,7 @@ [module] id = "whisper" name = "Whisper — speech-to-text" -version = "0.2.69" +version = "0.2.70" kind = "workload" category = "ai" status = "available" diff --git a/plugins/workflow-step/module.toml b/plugins/workflow-step/module.toml index 818a0aae..49421db3 100644 --- a/plugins/workflow-step/module.toml +++ b/plugins/workflow-step/module.toml @@ -14,7 +14,7 @@ [module] id = "workflow-step" name = "Workflow step — webhook workflow steps (meshhook)" -version = "0.2.69" +version = "0.2.70" kind = "workload" category = "infrastructure" status = "available"