Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
    npro  
 Modern all-safe Rust Network Protocol library supporting h1, h2, h3, ws, wt sans-IO and with socket IO + tls
git clone https://npro.rs/repo/npro
 
root / scripts / usr-local-svc-method-sai_builder-Solaris
Author[]Andy Green <andy@warmcat.com> 2025-08-27 13:43 UTC
Committer[]Andy Green <andy@warmcat.com> 2025-08-28 18:56 UTC
Tree1af5f5e312fb90b75e894cd3870ee36040209835   Raw Patch
 
refactor: Eliminate fixed instance concept
refactor: Eliminate fixed instance concept

Co-developed-by: Gemini 2.5 Pro
diff --git a/README.md b/README.md index 31acba2..0829e7c 100644 --- a/README.md +++ b/README.md @@ -297,7 +297,7 @@ sai-device|Helper that coordinates which builds wants and can use specific embed sai-expect|Helper run by embedded build flow to capture serial traffic and react to keywords sai-jig|Helper for embedded devices that lets another device control its buttons, reset etc as part of the embedded build flow -First you must build lws with appropriate options. +First you must build main branch lws with appropriate options. For redhat type distros, you probably need to add /usr/local/lib to the /etc/ld.so.conf before ldconfig can rgister the new libwebsockets.so @@ -305,20 +305,22 @@ For redhat type distros, you probably need to add /usr/local/lib to the ``` $ git clone https://libwebsockets.org/repo/libwebsockets $ cd libwebsockets && mkdir build && cd build && \ - cmake .. -DLWS_UNIX_SOCK=1 -DLWS_WITH_STRUCT_JSON=1 -DLWS_WITH_JOSE=1 \ - -DLWS_WITH_STRUCT_SQLITE3=1 -DLWS_WITH_GENCRYPTO=1 -DLWS_WITH_SPAWN=1 \ - -DLWS_WITH_SECURE_STREAMS=1 -DLWS_WITH_THREADPOOL=1 + cmake .. -DLWS_LOGS_TIMESTAMP=0 -DLWS_WITH_STRUCT_JSON=1 -DLWS_WITH_JOSE=1 \ + -DLWS_WITH_STRUCT_SQLITE3=1 -DLWS_WITH_GENCRYPTO=1 -DLWS_WITH_SPAWN=1 $ make -j && sudo make -j install && sudo ldconfig ``` The actual cmake options needed depends on if you are building sai-server and / or sai-builder. -Feature|lws options +lws cmake option|Meaning ---|--- -either|`-DLWS_WITH_STRUCT_JSON=1` `-DLWS_WITH_SECURE_STREAMS=1` -server|`-DLWS_UNIX_SOCK=1` `-DLWS_WITH_GENCRYPTO=1` `-DLWS_WITH_STRUCT_SQLITE3=1` `-DLWS_WITH_JOSE=1` -builder + related|`-DLWS_WITH_SPAWN=1` `-DLWS_WITH_THREADPOOL=1` +`-DLWS_LOGS_TIMESTAMP=0` | Avoids duplicating log timestamp in syslog +`-DLWS_WITH_STRUCT_JSON=1` | Support for struct -> JSON -> struct +`-DLWS_WITH_STRUCT_SQLITE3=1` | Support for struct -> sqlite3 -> struct +`-DLWS_WITH_SPAWN=1` | Support for crossplatform process spawning +`-DLWS_WITH_GENCRYPTO=1` | Supoort for cross-tls library crypto +`-DLWS_WITH_JOSE=1` | Support for JOSE web tokens You can also define `-DLWS_WITH_SYS_METRICS=1` on lws to enable build of openmetrics pieces in sai when built against lws. diff --git a/assets/sai.js b/assets/sai.js index 8bc7959..0bc7372 100644 --- a/assets/sai.js +++ b/assets/sai.js @@ -1006,16 +1006,12 @@ function createBuilderDiv(plat) { innerHTML += `<img class="ip1 tread1" src="/sai/arch-${plat_arch}.svg" onerror="this.src='/sai/generic.svg';this.onerror=null;">`; innerHTML += `<img class="ip1 tread2" src="/sai/tc-${plat_tc}.svg" onerror="this.src='/sai/generic.svg';this.onerror=null;">`; innerHTML += `<br>${plat.peer_ip}`; - innerHTML += `<div class="instload" id="instload-${plat.name}">`; - - // Create initial idle squares - for (let i = 0; i < plat.instances; i++) { - innerHTML += `<div class="inst_box inst_idle" title="instance ${i}: idle">` + - `<div class="inst_bar"></div>` + - `</div>`; - } - - innerHTML += `</div></td></tr></tbody></table>`; + innerHTML += `<div class="instload" id="instload-${plat.name}">` + + `<div class="inst_box inst_idle" title="active steps: 0">` + + `<div class="inst_text">0</div>` + + `<div class="inst_bar"></div>` + + `</div>` + + `</div></td></tr></tbody></table>`; platDiv.innerHTML = innerHTML; @@ -1601,74 +1597,41 @@ function ws_open_sai() break; case "com.warmcat.sai.loadreport": - if (!jso.platforms || !Array.isArray(jso.platforms)) { + const loadContainer = document.getElementById("instload-" + jso.builder_name); + if (!loadContainer) { break; } - for (const platformReport of jso.platforms) { - const platformName = platformReport.platform_name; - if (!platformName) { - continue; - } - - const loadContainer = document.getElementById("instload-" + platformName); - if (!loadContainer) { - continue; - } - - if (platformReport.loads && Array.isArray(platformReport.loads)) { - const instanceDivs = loadContainer.getElementsByClassName("inst_box"); - - for (let i = 0; i < platformReport.loads.length; i++) { - const instanceLoad = platformReport.loads[i]; - const instanceDiv = instanceDivs[i]; + const instanceDiv = loadContainer.querySelector(".inst_box"); + if (!instanceDiv) { + break; + } - if (!instanceDiv) { - break; - } + const textDiv = instanceDiv.querySelector(".inst_text"); + const barDiv = instanceDiv.querySelector(".inst_bar"); - let cpu = instanceLoad.cpu_percent / 10.0; - let stateText = instanceLoad.state ? 'busy' : 'idle'; - instanceDiv.title = `Instance ${i}: ${stateText}\nCPU: ${cpu.toFixed(1)}%`; + if (textDiv) { + textDiv.textContent = jso.active_steps; + } - if (instanceLoad.state) { - instanceDiv.classList.add("inst_busy"); - instanceDiv.classList.remove("inst_idle"); - } else { - instanceDiv.classList.add("inst_idle"); - instanceDiv.classList.remove("inst_busy"); - } + instanceDiv.title = `Active steps: ${jso.active_steps}\n` + + `CPU: ${(jso.cpu_percent / 10).toFixed(1)}%\n` + + `Free RAM: ${humanize(jso.free_ram_kib * 1024)}B\n` + + `Free Disk: ${humanize(jso.free_disk_kib * 1024)}B`; + + if (jso.active_steps > 0) { + instanceDiv.classList.add("inst_busy"); + instanceDiv.classList.remove("inst_idle"); + } else { + instanceDiv.classList.add("inst_idle"); + instanceDiv.classList.remove("inst_busy"); + } - // The bar is always the first (and only) child of the inst_box div. - const bar = instanceDiv.firstChild; - if (bar && bar.classList.contains("inst_bar")) { - // cpu_percent is in tenths of a percent, relative to ONE core. - // So 1000 = 100% = 1 full core. - let total_cpu_capacity = jso.core_count * 1000; - - // Normalize the load to be a percentage of the ENTIRE system's capacity - let cpu_percentage = (instanceLoad.cpu_percent / total_cpu_capacity) * 100; - - if (cpu_percentage > 100) cpu_percentage = 100; - if (cpu_percentage < 0) cpu_percentage = 0; - if (cpu_percentage > 0 && cpu_percentage < 1) cpu_percentage = 1; - - bar.style.height = `${cpu_percentage}%`; - - // Update the class for idle/busy state - if (instanceLoad.state) { // state == 1 means busy - instanceDiv.classList.add("inst_busy"); - instanceDiv.classList.remove("inst_idle"); - } else { // state == 0 means idle - instanceDiv.classList.add("inst_idle"); - instanceDiv.classList.remove("inst_busy"); - } - } else { - // This console log will tell us if the bar element is missing - console.error("Could not find .inst_bar child in .inst_box for", instanceDiv); - } - } - } + if (barDiv) { + let cpu_percentage = (jso.cpu_percent / (jso.core_count * 1000)) * 100; + if (cpu_percentage > 100) cpu_percentage = 100; + if (cpu_percentage < 0) cpu_percentage = 0; + barDiv.style.height = `${cpu_percentage}%`; } break; diff --git a/src/builder/b-comms.c b/src/builder/b-comms.c index 8f955e4..7b21996 100644 --- a/src/builder/b-comms.c +++ b/src/builder/b-comms.c @@ -170,11 +170,6 @@ saib_m_tx(void *userobj, lws_ss_tx_ordinal_t ord, uint8_t *buf, size_t *len, n = (int)w; lws_dll2_remove(&lr->list); - lws_start_foreach_dll_safe(struct lws_dll2 *, il, il1, lr->platforms.head) { - sai_platform_load_t *i = lws_container_of(il, sai_platform_load_t, list); - lws_dll2_remove(&i->list); - free(i); - } lws_end_foreach_dll_safe(il, il1); free(lr); r = lws_ss_request_tx(spm->ss); @@ -484,52 +479,21 @@ saib_sul_load_report_cb(struct lws_sorted_usec_list *sul) lr->core_count = saib_get_cpu_count(); lr->free_ram_kib = saib_get_free_ram_kib(); lr->free_disk_kib = saib_get_free_disk_kib(builder.home); - - int system_load = saib_get_system_cpu(&builder); - - /* - * Iterate all platforms. For each platform, create a sai_platform_load_t - * and populate its list of instance loads. - */ + lr->cpu_percent = (unsigned int)saib_get_system_cpu(&builder); + lr->active_steps = 0; lws_start_foreach_dll(struct lws_dll2 *, p, builder.sai_plat_owner.head) { sp = lws_container_of(p, sai_plat_t, sai_plat_list); - - sai_platform_load_t *pl = calloc(1, sizeof(*pl)); - if (!pl) - continue; - - lws_strncpy(pl->platform_name, sp->name, sizeof(pl->platform_name)); - lws_start_foreach_dll(struct lws_dll2 *, d, sp->nspawn_owner.head) { - struct sai_nspawn *ns = lws_container_of(d, struct sai_nspawn, list); - sai_instance_load_t *il = calloc(1, sizeof(*il)); - int load = -1; - - if (il) { - il->state = (ns->state == NSSTATE_EXECUTING_STEPS); - - if (!il->state) { - /* If the instance is idle, its load is 0, regardless of system load. */ - load = 0; - } else { - somebody_not_idle = 1; - /* The instance is busy, try to get a specific load for it. */ - load = saib_get_cgroup_cpu(ns); - if (load < 0) - /* Fall back to system load for busy instances on non-cgroup platforms. */ - load = system_load; - } - - if (load < 0) /* Final fallback for errors */ - load = 10; /* Default to 1% if system load failed */ - - il->cpu_percent = (uint16_t)load; - lws_dll2_add_tail(&il->list, &pl->loads); + struct sai_nspawn *ns = lws_container_of(d, + struct sai_nspawn, list); + if (ns->state == NSSTATE_EXECUTING_STEPS) { + lr->active_steps++; + somebody_not_idle = 1; } } lws_end_foreach_dll(d); - lws_dll2_add_tail(&pl->list, &lr->platforms); +// lws_dll2_add_tail(&pl->list, &lr->platforms); } lws_end_foreach_dll(p); lws_dll2_add_tail(&lr->list, &spm->load_report_owner); @@ -542,7 +506,6 @@ saib_sul_load_report_cb(struct lws_sorted_usec_list *sul) saib_sul_load_report_cb, SAI_LOAD_REPORT_US); } - static lws_ss_state_return_t saib_m_state(void *userobj, void *sh, lws_ss_constate_t state, lws_ss_tx_ordinal_t ack) diff --git a/src/builder/b-conf.c b/src/builder/b-conf.c index 3d9bda7..a35e256 100644 --- a/src/builder/b-conf.c +++ b/src/builder/b-conf.c @@ -68,7 +68,6 @@ enum enum_paths_global { static const char * const paths[] = { "platforms[].name", - "platforms[].instances", "platforms[].env[].*", "platforms[].env[]", "platforms[].servers", @@ -78,7 +77,6 @@ static const char * const paths[] = { enum enum_paths { LEJPM_PLATFORMS_NAME, - LEJPM_PLATFORMS_INSTANCES, LEJPM_PLATFORMS_ENV_ITEM, LEJPM_PLATFORMS_ENV, LEJPM_PLATFORMS_SERVERS, @@ -113,8 +111,6 @@ saib_conf_cb(struct lejp_ctx *ctx, char reason) if (!a->sai_plat) return -1; - a->sai_plat->instances = 1; /* default */ - lws_strncpy(a->sai_plat->sai_hash, BUILD_INFO, sizeof(a->sai_plat->sai_hash)); lws_strncpy(a->sai_plat->lws_hash, LWS_BUILD_HASH, @@ -136,38 +132,6 @@ saib_conf_cb(struct lejp_ctx *ctx, char reason) if (!(reason & LEJP_FLAG_CB_IS_VALUE) || !ctx->path_match) return 0; - if (reason == LEJPCB_VAL_NUM_INT) { - n = atoi(ctx->buf); - switch (ctx->path_match - 1) { - - case LEJPM_PLATFORMS_INSTANCES: - lwsl_notice("%s: instances %d\n", __func__, n); - a->sai_plat->instances = n; - /* - * Instantiate n nspawns bound to this platform - */ - - for (n = 0; n < a->sai_plat->instances; n++) { - struct sai_nspawn *ns = malloc(sizeof(*ns)); - if (!ns) - return -1; - - memset(ns, 0, sizeof(*ns)); - ns->instance_idx = n; - ns->builder = &builder; - ns->sp = a->sai_plat; - ns->task = NULL; - lws_dll2_add_head(&ns->list, - &a->sai_plat->nspawn_owner); - } - break; - - default: - break; - } - - return 0; - } if (reason != LEJPCB_VAL_STR_END) return 0; diff --git a/src/builder/b-metrics.c b/src/builder/b-metrics.c index b577f73..170fcdc 100644 --- a/src/builder/b-metrics.c +++ b/src/builder/b-metrics.c @@ -25,6 +25,8 @@ #if defined(__linux__) #include <sys/statvfs.h> #elif defined(__APPLE__) +#include <sys/mount.h> +#include <sys/param.h> #include <sys/sysctl.h> #include <mach/mach.h> #include <mach/vm_statistics.h> @@ -50,23 +52,17 @@ saib_get_free_ram_kib(void) fclose(f); return free_kib; #elif defined(__APPLE__) - int mib[2]; - size_t len; - uint64_t total_mem; - vm_size_t page_size; - mach_msg_type_number_t count; + mach_msg_type_number_t count = HOST_VM_INFO64_COUNT; vm_statistics64_data_t vm_stats; + vm_size_t page_size; - mib[0] = CTL_HW; - mib[1] = HW_MEMSIZE; - len = sizeof(total_mem); - sysctl(mib, 2, &total_mem, &len, NULL, 0); - - count = HOST_VM_INFO64_COUNT; - if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t)&vm_stats, &count) != KERN_SUCCESS) + if (host_statistics64(mach_host_self(), HOST_VM_INFO64, + (host_info64_t)&vm_stats, &count) != KERN_SUCCESS) return 0; - return (unsigned int)((uint64_t)vm_stats.free_count * vm_stats.pagesize / 1024); + host_page_size(mach_host_self(), &page_size); + + return (unsigned int)((uint64_t)vm_stats.free_count * page_size / 1024); #elif defined(_WIN32) MEMORYSTATUSEX statex; statex.dwLength = sizeof(statex); @@ -80,13 +76,20 @@ saib_get_free_ram_kib(void) unsigned int saib_get_free_disk_kib(const char *path) { -#if defined(__linux__) || defined(__APPLE__) +#if defined(__linux__) struct statvfs s; if (statvfs(path, &s)) return 0; return (unsigned int)((uint64_t)s.f_bavail * s.f_frsize / 1024); +#elif defined(__APPLE__) + struct statfs s; + + if (statfs(path, &s)) + return 0; + + return (unsigned int)((uint64_t)s.f_bavail * (uint64_t)s.f_bsize / 1024); #elif defined(_WIN32) ULARGE_INTEGER free_bytes; diff --git a/src/builder/b-nspawn.c b/src/builder/b-nspawn.c index a53ce35..1c3a022 100644 --- a/src/builder/b-nspawn.c +++ b/src/builder/b-nspawn.c @@ -157,10 +157,7 @@ sai_lsp_reap_cb(void *opaque, const lws_spawn_resource_us_t *res, siginfo_t *si, { struct saib_opaque_spawn *op = (struct saib_opaque_spawn *)opaque; struct sai_nspawn *ns = op ? op->ns : NULL; - - // lwsl_warn("%s: reap at %llu: we_killed_him: %d\n", __func__, - // (unsigned long long)lws_now_usecs(), we_killed_him); - + uint64_t us_wallclock = op ? (uint64_t)(lws_now_usecs() - op->start_time) : 0; int exit_code = -1; char s[256]; int n; @@ -218,29 +215,36 @@ sai_lsp_reap_cb(void *opaque, const lws_spawn_resource_us_t *res, siginfo_t *si, lws_dir(ns->inp, &du, lws_dir_du_cb); { - char h1[40], h2[40], h3[40], h4[40], h5[40], h6[40], h7[40], h8[40]; + char h1[40], h2[40], h3[40], h4[40], h5[40], h6[40], h7[40], h8[40], h9[40], h10[40]; ns->us_cpu_user += res->us_cpu_user; ns->us_cpu_sys += res->us_cpu_sys; + ns->us_wallclock += us_wallclock; if (du.size_in_bytes > ns->worst_stg) ns->worst_stg = du.size_in_bytes; if (res->peak_mem_rss > ns->worst_mem) ns->worst_mem = res->peak_mem_rss; - lws_humanize(h1, sizeof(h1), ns->us_cpu_user, humanize_schema_us); - lws_humanize(h2, sizeof(h2), ns->us_cpu_sys, humanize_schema_us); - lws_humanize(h3, sizeof(h3), ns->worst_mem, humanize_schema_si); - lws_humanize(h4, sizeof(h4), ns->worst_stg, humanize_schema_si); - lws_humanize(h5, sizeof(h5), res->us_cpu_user, humanize_schema_us); - lws_humanize(h6, sizeof(h6), res->us_cpu_sys, humanize_schema_us); - lws_humanize(h7, sizeof(h7), res->peak_mem_rss, humanize_schema_si); - lws_humanize(h8, sizeof(h8), du.size_in_bytes, humanize_schema_si); + lws_humanize_pad(h1, sizeof(h1), ns->us_cpu_user, humanize_schema_us); + lws_humanize_pad(h2, sizeof(h2), ns->us_cpu_sys, humanize_schema_us); + lws_humanize_pad(h3, sizeof(h3), ns->worst_mem, humanize_schema_si); + lws_humanize_pad(h4, sizeof(h4), ns->worst_stg, humanize_schema_si); + lws_humanize_pad(h5, sizeof(h5), res->us_cpu_user, humanize_schema_us); + lws_humanize_pad(h6, sizeof(h6), res->us_cpu_sys, humanize_schema_us); + lws_humanize_pad(h7, sizeof(h7), res->peak_mem_rss, humanize_schema_si); + lws_humanize_pad(h8, sizeof(h8), du.size_in_bytes, humanize_schema_si); + lws_humanize_pad(h9, sizeof(h9), us_wallclock, humanize_schema_us); + lws_humanize_pad(h10, sizeof(h10), ns->us_wallclock, humanize_schema_us); + + n = lws_snprintf(s, sizeof(s), + ">saib> Step %d: [ %s (%s u / %s s), Mem: %sB, Stg: %sB ]\n", + ns->current_step + 1, h9, h5, h6, h7, h8); + saib_log_chunk_create(ns, s, (size_t)n, 3); n = lws_snprintf(s, sizeof(s), - ">saib> Step %d: Total [ %s u / %s s, Mem: %sB, Stg: %sB ], Step [ %s u / %s s, Mem: %sB, Stg: %sB ]\n", - ns->current_step + 1, h1, h2, h3, h4, h5, h6, h7, h8); - + ">saib> Task: [ %s (%s u / %s s), Mem: %sB, Stg: %sB ]\n", + h10, h1, h2, h3, h4); saib_log_chunk_create(ns, s, (size_t)n, 3); } @@ -274,7 +278,7 @@ sai_lsp_reap_cb(void *opaque, const lws_spawn_resource_us_t *res, siginfo_t *si, lws_strncpy(m->ref, ns->ref, sizeof(m->ref)); m->us_cpu_user = res->us_cpu_user; m->us_cpu_sys = res->us_cpu_sys; - m->wallclock_us = (uint64_t)(lws_now_usecs() - op->start_time); + m->wallclock_us = us_wallclock; m->peak_mem_rss = res->peak_mem_rss; m->stg_bytes = du.size_in_bytes; @@ -435,7 +439,7 @@ saib_spawn_script(struct sai_nspawn *ns) { struct lws_spawn_piped_info info; struct saib_opaque_spawn *op; - char args[290], st[2048], *p; + char st[2048]; const char *respath = "unk"; const char * cmd[] = { "/bin/ps", @@ -452,32 +456,28 @@ saib_spawn_script(struct sai_nspawn *ns) char cgroup[128]; #endif - lws_strncpy(st, ns->sp->name, sizeof(st)); - lws_filename_purify_inplace(st); - p = st; - while ((p = strchr(p, '/'))) - *p = '_'; - #if defined(WIN32) - lws_snprintf(args, sizeof(args), "%s\\sai-build-script-%s-%d.bat", - builder.home, st, ns->instance_idx); + lws_snprintf(ns->script_path, sizeof(ns->script_path), + "%s\\sai-build-script-%s.bat", + builder.home, ns->task->uuid); #else - lws_snprintf(args, sizeof(args), "%s/sai-build-script-%s-%d.sh", - builder.home, st, ns->instance_idx); + lws_snprintf(ns->script_path, sizeof(ns->script_path), + "%s/sai-build-script-%s.sh", + builder.home, ns->task->uuid); #endif char one_step[4096]; lws_strncpy(one_step, ns->task->script, sizeof(one_step)); #if defined(WIN32) - if (_sopen_s(&fd, args, _O_CREAT | _O_TRUNC | _O_WRONLY, + if (_sopen_s(&fd, ns->script_path, _O_CREAT | _O_TRUNC | _O_WRONLY, _SH_DENYNO, _S_IWRITE)) fd = -1; #else - fd = open(args, O_CREAT | O_TRUNC | O_WRONLY, 0755); + fd = open(ns->script_path, O_CREAT | O_TRUNC | O_WRONLY, 0755); #endif if (fd < 0) { - lwsl_err("%s: unable to open %s for write\n", __func__, args); + lwsl_err("%s: unable to open %s for write\n", __func__, ns->script_path); return 1; } @@ -521,13 +521,13 @@ saib_spawn_script(struct sai_nspawn *ns) if (write(fd, st, (unsigned int)n) != n) { close(fd); - lwsl_err("%s: failed to write runscript to %s\n", __func__, args); + lwsl_err("%s: failed to write runscript to %s\n", __func__, ns->script_path); return 1; } close(fd); - cmd[0] = args; + cmd[0] = ns->script_path; #if defined(__linux__) lws_snprintf(cgroup, sizeof(cgroup), "inst-%u-%d", (unsigned int)getpid(), ns->instance_idx); diff --git a/src/builder/b-private.h b/src/builder/b-private.h index 7146d14..5de8992 100644 --- a/src/builder/b-private.h +++ b/src/builder/b-private.h @@ -208,7 +208,7 @@ rm_rf_cb(const char *dirpath, void *user, struct lws_dir_entry *lde); extern const struct lws_protocols protocol_logproxy, protocol_resproxy; void * -thread_suspend(void *d); +saib_thread_suspend(void *d); int diff --git a/src/builder/b-sai.c b/src/builder/b-sai.c index 9ca1b55..a2ef7bd 100644 --- a/src/builder/b-sai.c +++ b/src/builder/b-sai.c @@ -312,8 +312,8 @@ saib_power_stay_rx(void *userobj, const uint8_t *buf, size_t len, int flags) struct sai_plat *sp = lws_container_of(mp, struct sai_plat, sai_plat_list); - if (sp->ongoing) { - lwsl_warn("%s: cancelling idle grace time as ongoing tasks\n", __func__); + if (sp->nspawn_owner.count) { + lwsl_warn("%s: cancelling idle grace time as ongoing task steps\n", __func__); lws_sul_cancel(&builder.sul_idle); return 0; } @@ -759,9 +759,11 @@ int main(int argc, const char **argv) */ while (n >= 0) { +#if !defined(WIN32) int status; - uint8_t d; pid_t p; +#endif + uint8_t d; n = read(0, &d, 1); lwsl_notice("%s: suspend process read returned %d\n", __func__, (int)n); diff --git a/src/builder/b-task.c b/src/builder/b-task.c index 51ea66a..a4c4448 100644 --- a/src/builder/b-task.c +++ b/src/builder/b-task.c @@ -134,9 +134,6 @@ saib_queue_task_status_update(sai_plat_t *sp, struct sai_plat_server *spm, lws_snprintf(rej->host_platform, sizeof(rej->host_platform), "%s", sp->name); - rej->limit = sp->instances; - rej->ongoing = sp->ongoing; - lws_dll2_add_tail(&rej->list, &spm->rejection_list); return lws_ss_request_tx(spm->ss) ? -1 : 0; @@ -153,45 +150,35 @@ saib_task_destroy(struct sai_nspawn *ns) * If able, builder should reintroduce himself to get * another task */ + if (ns->spm) { ns->spm->phase = PHASE_START_ATTACH; if (lws_ss_request_tx(ns->spm->ss)) return; } + if (ns->list.owner && ns->list.owner->count == 1) { + int m = 0; - if (ns->task && ns->task->told_ongoing) { /* - * Account that we're not doing this task any more + * Is it the case that none of the platforms have + * any ongoing jobs then? We don't any more. + * + * If nobody does, start the grace time for suspend. */ - // lwsl_notice("%s: ongoing %d -> %d\n", __func__, - // ns->sp->ongoing, ns->sp->ongoing - 1); - ns->sp->ongoing--; - - if (!ns->sp->ongoing) { - int m = 0; - - /* - * Is it the case that none of the platforms have - * any ongoing jobs then? We don't any more. - * - * If nobody does, start the grace time for suspend. - */ - - lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1, - builder.sai_plat_owner.head) { - struct sai_plat *sp = lws_container_of(d, - struct sai_plat, sai_plat_list); - if (sp->ongoing) - m++; - } lws_end_foreach_dll_safe(d, d1); + lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1, + builder.sai_plat_owner.head) { + struct sai_plat *sp = lws_container_of(d, + struct sai_plat, sai_plat_list); + if (sp->nspawn_owner.count) + m++; + } lws_end_foreach_dll_safe(d, d1); - if (!m) - lws_sul_schedule(builder.context, 0, - &builder.sul_idle, sul_idle_cb, - SAI_IDLE_GRACE_US); - } + if (!m) + lws_sul_schedule(builder.context, 0, + &builder.sul_idle, sul_idle_cb, + SAI_IDLE_GRACE_US); /* * Schedule informing all the servers we're connected to @@ -205,6 +192,12 @@ saib_task_destroy(struct sai_nspawn *ns) lwsac_free(&ns->task->ac_task_container); ns->task = NULL; } + + if (ns->script_path[0]) + unlink(ns->script_path); + + lws_dll2_remove(&ns->list); + free(ns); } static void @@ -540,19 +533,13 @@ saib_ws_json_rx_builder(struct sai_plat_server *spm, const void *in, size_t len) } lws_end_foreach_dll_safe(d, d1); if (!ns) { - - /* - * Full up... reject the task and update every - * server's model of our task load status - */ - - lwsl_notice("%s: plat '%s': no idle nspawn (of %d), " - "plat load %d / %d\n", __func__, sp->name, - n, sp->ongoing, sp->instances); - if (saib_queue_task_status_update(sp, spm, task->uuid)) + ns = malloc(sizeof(*ns)); + if (!ns) return -1; - - return 0; + memset(ns, 0, sizeof(*ns)); + ns->builder = &builder; + ns->sp = sp; + lws_dll2_add_tail(&ns->list, &sp->nspawn_owner); } // lwsl_hexdump_warn(task->build, strlen(task->build)); @@ -662,17 +649,6 @@ saib_ws_json_rx_builder(struct sai_plat_server *spm, const void *in, size_t len) goto bail; } - /* - * If we successfully set the threadpool task up, then we - * bump our idea of what is ongoing... completing or failing - * after that needs to adjust sp->ongoing accordingly - */ - - lwsl_notice("%s: ongoing %d -> %d\n", __func__, sp->ongoing, - sp->ongoing + 1); - sp->ongoing++; - ns->task->told_ongoing = 1; - /* we're busy, we're not in the mood for suspending */ lwsl_notice("%s: cancelling suspend grace time\n", __func__); lws_sul_cancel(&ns->builder->sul_idle); diff --git a/src/common/include/private.h b/src/common/include/private.h index 6b017a1..4219c94 100644 --- a/src/common/include/private.h +++ b/src/common/include/private.h @@ -60,33 +60,15 @@ enum { SAISPRF_SIGNALLED = 0x4000, }; -/* - * per-instance load data. - * Sent from builder -> server -> web -> browser. - */ -typedef struct sai_instance_load { - lws_dll2_t list; - unsigned int cpu_percent; /* CPU usage for this instance * 100 */ - unsigned int state; /* 0 = idle, 1 = running */ -} sai_instance_load_t; - -/* - * load report struct, sent in its own schema. - */ -typedef struct sai_platform_load { - lws_dll2_t list; /* Not used, for schema mapping */ - char platform_name[128]; - lws_dll2_owner_t loads; -} sai_platform_load_t; - /* The top-level load report message from a builder */ typedef struct sai_load_report { lws_dll2_t list; /* For queuing on sai_plat_server */ char builder_name[64]; int core_count; - lws_dll2_owner_t platforms; /* List of sai_platform_load_t */ unsigned int free_ram_kib; unsigned int free_disk_kib; + unsigned int active_steps; + unsigned int cpu_percent; } sai_load_report_t; /* @@ -98,6 +80,12 @@ typedef struct sai_viewer_state { unsigned int viewers; } sai_viewer_state_t; +typedef struct sai_platform_load { + lws_dll2_t list; /* Not used, for schema mapping */ + char platform_name[128]; + lws_dll2_owner_t loads; +} sai_platform_load_t; + struct sai_nspawn; @@ -134,8 +122,6 @@ typedef struct { int state; int uid; int build_step; - - char told_ongoing; } sai_task_t; typedef struct sai_plat sai_plat_t; @@ -156,6 +142,7 @@ struct sai_nspawn { char inp[512]; char path[384]; + char script_path[290]; char pending_mirror_log[128]; /* convenient place to store it */ @@ -182,8 +169,9 @@ struct sai_nspawn { uint64_t last_cpu_usec; lws_usec_t last_cpu_usec_time; - uint64_t us_cpu_user; - uint64_t us_cpu_sys; + uint64_t us_wallclock; + uint64_t us_cpu_user; + uint64_t us_cpu_sys; uint64_t worst_mem; uint64_t worst_stg; @@ -221,8 +209,6 @@ typedef struct sai_rejection { struct lws_dll2 list; char host_platform[65]; char task_uuid[65]; - int ongoing; - int limit; } sai_rejection_t; /* @@ -443,9 +429,6 @@ typedef struct sai_plat { int powering_up; /* 1 = sai-power is booting it */ int powering_down; - int instances; - int ongoing; - char windows; int index; /* used to create unique build dir path */ @@ -530,7 +513,7 @@ extern const lws_struct_map_t lsm_log[7], lsm_artifact[8], lsm_plat_list[1], - lsm_task_rej[4], + lsm_task_rej[2], lsm_task_cancel[1], lsm_schema_json_map_can[1], lsm_schema_json_map_task[1], @@ -543,8 +526,8 @@ extern const lws_struct_map_t lsm_schema_sq3_map_build_metric[1] ; extern const lws_struct_map_t lsm_build_metric[9]; -extern const lws_struct_map_t lsm_plat[9]; -extern const lws_struct_map_t lsm_plat_for_json[13]; +extern const lws_struct_map_t lsm_plat[8]; +extern const lws_struct_map_t lsm_plat_for_json[11]; extern const lws_ss_info_t ssi_said_logproxy; extern struct lws_ss_handle *ssh[3]; diff --git a/src/common/struct-metadata.c b/src/common/struct-metadata.c index 7d62719..4453ddf 100644 --- a/src/common/struct-metadata.c +++ b/src/common/struct-metadata.c @@ -21,25 +21,15 @@ * lws_struct metadata for structs common to builder and server */ -const lws_struct_map_t lsm_instance_load[] = { - LSM_UNSIGNED (sai_instance_load_t, cpu_percent, "cpu_percent"), - LSM_UNSIGNED (sai_instance_load_t, state, "state"), -}; - -/* Map for a sai_platform_load_t object */ -const lws_struct_map_t lsm_platform_load[] = { - LSM_CARRAY(sai_platform_load_t, platform_name, "platform_name"), - LSM_LIST(sai_platform_load_t, loads, sai_instance_load_t, list, - NULL, lsm_instance_load, "loads"), -}; - const lws_struct_map_t lsm_load_report_members[] = { LSM_CARRAY (sai_load_report_t, builder_name, "builder_name"), LSM_SIGNED (sai_load_report_t, core_count, "core_count"), LSM_UNSIGNED (sai_load_report_t, free_ram_kib, "free_ram_kib"), LSM_UNSIGNED (sai_load_report_t, free_disk_kib, "free_disk_kib"), - LSM_LIST (sai_load_report_t, platforms, sai_platform_load_t, list, - NULL, lsm_platform_load, "platforms"), + LSM_UNSIGNED (sai_load_report_t, active_steps, "active_steps"), + LSM_UNSIGNED (sai_load_report_t, cpu_percent, "cpu_percent"), +// LSM_LIST (sai_load_report_t, platforms, sai_platform_load_t, list, +// NULL, lsm_platform_load, "platforms"), }; const lws_struct_map_t lsm_build_metric[] = { @@ -78,7 +68,6 @@ const lws_struct_map_t lsm_schema_sq3_map_build_metric[] = { const lws_struct_map_t lsm_plat[] = { /* !!! keep extern length in common/include/private.h in sync */ LSM_UNSIGNED (sai_plat_t, uid, "uid"), LSM_STRING_PTR (sai_plat_t, name, "name"), - LSM_UNSIGNED (sai_plat_t, instances, "instances"), LSM_STRING_PTR (sai_plat_t, platform, "platform"), LSM_UNSIGNED (sai_plat_t, last_seen, "last_seen"), LSM_CARRAY (sai_plat_t, peer_ip, "peer_ip"), @@ -91,8 +80,6 @@ const lws_struct_map_t lsm_plat[] = { /* !!! keep extern length in common/includ const lws_struct_map_t lsm_plat_for_json[] = { LSM_UNSIGNED(sai_plat_t, uid, "uid"), LSM_STRING_PTR(sai_plat_t, name, "name"), - LSM_SIGNED(sai_plat_t, ongoing, "ongoing"), // MUST be present - LSM_SIGNED(sai_plat_t, instances, "instances"), LSM_STRING_PTR(sai_plat_t, platform,"platform"), LSM_SIGNED(sai_plat_t, online, "online"), // MUST be present LSM_UNSIGNED(sai_plat_t, last_seen, "last_seen"), @@ -192,8 +179,6 @@ const lws_struct_map_t lsm_schema_sq3_map_task[] = { const lws_struct_map_t lsm_task_rej[] = { LSM_CARRAY (sai_rejection_t, host_platform, "host_platform"), LSM_CARRAY (sai_rejection_t, task_uuid, "task_uuid"), - LSM_UNSIGNED (sai_rejection_t, ongoing, "ongoing"), - LSM_UNSIGNED (sai_rejection_t, limit, "limit"), }; const lws_struct_map_t lsm_schema_json_task_rej[] = { diff --git a/src/server/s-central.c b/src/server/s-central.c index 17808f6..9ccb5c6 100644 --- a/src/server/s-central.c +++ b/src/server/s-central.c @@ -160,11 +160,7 @@ sais_central_cb(lws_sorted_usec_list_t *sul) vhd->server.builder_owner.head) { sai_plat_t *cb = lws_container_of(p, sai_plat_t, sai_plat_list); - lwsl_debug("%s: checking tasks %s %d %d %p\n", __func__, - cb->name, cb->ongoing, cb->instances, cb->wsi); - - if (cb->wsi && lws_wsi_user(cb->wsi) && - cb->ongoing < cb->instances) + if (cb->wsi && lws_wsi_user(cb->wsi)) /* * try to bind outstanding task to specific builder * instance diff --git a/src/server/s-task.c b/src/server/s-task.c index 10934d9..21525d3 100644 --- a/src/server/s-task.c +++ b/src/server/s-task.c @@ -803,9 +803,6 @@ sais_allocate_task(struct vhd *vhd, struct pss *pss, sai_plat_t *cb, const sai_task_t *task_template; sai_task_t *task = NULL; - if (cb->ongoing >= cb->instances) - return 1; - /* * Look for a task for this platform, on any event that needs building */ diff --git a/src/server/s-websrv.c b/src/server/s-websrv.c index f4073a2..789898a 100644 --- a/src/server/s-websrv.c +++ b/src/server/s-websrv.c @@ -257,13 +257,10 @@ sais_list_builders(struct vhd *vhd) if (live_builder) { builder_from_db->online = 1; - builder_from_db->ongoing = live_builder->ongoing; lws_strncpy(builder_from_db->peer_ip, live_builder->peer_ip, sizeof(builder_from_db->peer_ip)); - } else { + } else builder_from_db->online = 0; - builder_from_db->ongoing = 0; - } builder_from_db->powering_up = 0; builder_from_db->powering_down = 0; diff --git a/src/server/s-ws-builder.c b/src/server/s-ws-builder.c index dc100f3..3094801 100644 --- a/src/server/s-ws-builder.c +++ b/src/server/s-ws-builder.c @@ -57,22 +57,21 @@ typedef struct sais_logcache_pertask { } sais_logcache_pertask_t; /* map for a single instance's load */ -static const lws_struct_map_t lsm_instance_load[] = { - LSM_UNSIGNED(sai_instance_load_t, cpu_percent, "cpu_percent"), - LSM_UNSIGNED(sai_instance_load_t, state, "state"), -}; +//static const lws_struct_map_t lsm_instance_load[] = { +// LSM_UNSIGNED(sai_instance_load_t, state, "state"), +//}; -static const lws_struct_map_t lsm_platform_load[] = { - LSM_CARRAY(sai_platform_load_t, platform_name, "platform_name"), - LSM_LIST(sai_platform_load_t, loads, sai_instance_load_t, list, - NULL, lsm_instance_load, "loads"), -}; +// static const lws_struct_map_t lsm_platform_load[] = { +// LSM_CARRAY(sai_platform_load_t, platform_name, "platform_name"), +// LSM_LIST(sai_platform_load_t, loads, sai_instance_load_t, list, +// NULL, lsm_instance_load, "loads"), +//}; /* map for the members of the load report object */ static const lws_struct_map_t lsm_load_report_members[] = { LSM_CARRAY(sai_load_report_t, builder_name, "builder_name"), - LSM_LIST (sai_load_report_t, platforms, sai_platform_load_t, list, - NULL, lsm_platform_load, "platforms"), +// LSM_LIST (sai_load_report_t, platforms, sai_platform_load_t, list, +// NULL, lsm_platform_load, "platforms"), }; /* @@ -281,7 +280,7 @@ sais_builder_from_uuid(struct vhd *vhd, const char *hostname, const char *_file, sai_plat_list); if (!strcmp(hostname, cb->name)) { - lwsl_err("%s: %s:%d: found live builder %s\n", __func__, _file, _line, hostname); + lwsl_info("%s: %s:%d: found live builder %s\n", __func__, _file, _line, hostname); cb->online = 1; return cb; } @@ -501,6 +500,8 @@ sais_ws_json_rx_builder(struct vhd *vhd, struct pss *pss, uint8_t *buf, size_t b memset(&pss->a, 0, sizeof(pss->a)); pss->a.map_st[0] = lsm_schema_map_ba; pss->a.map_entries_st[0] = LWS_ARRAY_SIZE(lsm_schema_map_ba); + pss->a.map_st[1] = lsm_schema_map_ba; + pss->a.map_entries_st[1] = LWS_ARRAY_SIZE(lsm_schema_map_ba); pss->a.ac_block_size = 4096; lws_struct_json_init_parse(&pss->ctx, NULL, &pss->a); @@ -572,7 +573,6 @@ handle: /* Already exists (reconnect), just update dynamic info */ lwsl_err("%s: found live builder for %s\n", __func__, build->name); live_cb->wsi = pss->wsi; - live_cb->ongoing = 0; /* Reset ongoing task count on connect */ lws_strncpy(live_cb->peer_ip, pss->peer_ip, sizeof(live_cb->peer_ip)); lws_strncpy(live_cb->sai_hash, build->sai_hash, sizeof(live_cb->sai_hash)); @@ -595,7 +595,6 @@ handle: memcpy(p_str, build->name, nlen); live_cb->platform = p_str + nlen; memcpy(p_str + nlen, build->platform, plen); - live_cb->instances = build->instances; lws_strncpy(live_cb->sai_hash, build->sai_hash, sizeof(live_cb->sai_hash)); lws_strncpy(live_cb->lws_hash, build->lws_hash, @@ -720,13 +719,8 @@ bail: break; } - /* update our info about builder state with reality */ - - cb->ongoing = rej->ongoing; - cb->instances = rej->limit; - - lwsl_notice("%s: builder %s reports occupancy %d/%d (rej %s)\n", - __func__, cb->name, cb->ongoing, cb->instances, + lwsl_notice("%s: builder %s reports rejection (rej %s)\n", + __func__, cb->name, rej->task_uuid[0] ? rej->task_uuid : "none"); if (rej->task_uuid[0]) @@ -736,6 +730,13 @@ bail: break; case SAIM_WSSCH_BUILDER_LOADREPORT: + { + sai_load_report_t *lr = (sai_load_report_t *)pss->a.dest; + + lwsl_notice("%s: loadreport from %s: ram %uk, disk %uk\n", + __func__, lr->builder_name, lr->free_ram_kib, + lr->free_disk_kib); + } // lwsl_wsi_user(pss->wsi, "SAIM_WSSCH_BUILDER_LOADREPORT broadcasting\n"); sais_websrv_broadcast(vhd->h_ss_websrv, (const char *)buf, bl); break; diff --git a/src/web/w-ws-browser.c b/src/web/w-ws-browser.c index 8767cb6..743d3ce 100644 --- a/src/web/w-ws-browser.c +++ b/src/web/w-ws-browser.c @@ -57,7 +57,7 @@ saiw_ws_broadcast_raw(struct vhd *vhd, const void *buf, size_t len, unsigned int // lwsl_notice("%s: broadcast to %d / %d browsers\n", __func__, eff, (int)vhd->browsers.count); } -extern const lws_struct_map_t lsm_load_report_members[2]; +extern const lws_struct_map_t lsm_load_report_members[7]; /* * For decoding specific event data request from browser
Page fetched 0s ago, creation time: 14ms (vhost etag hits: 0%, cache hits: 0%)