| 431 | } |
| 432 | |
| 433 | static void host_http_reconcile_at(host_state_t *host, uint64_t now_ms, bool force_config_load) { |
| 434 | if (!host || !host->http_ops) { |
| 435 | return; |
| 436 | } |
| 437 | if (!force_config_load && host->http_config_loaded && now_ms < host->http_next_config_load_ms) { |
| 438 | return; |
| 439 | } |
| 440 | host->http_next_config_load_ms = host_deadline_from(now_ms, HOST_HTTP_CONFIG_POLL_MS); |
| 441 | |
| 442 | cbm_ui_config_t desired; |
| 443 | host->http_ops->config_load(host->http_ops->context, &desired); |
| 444 | bool config_changed = !host->http_config_loaded || |
| 445 | desired.ui_enabled != host->http_config_enabled || |
| 446 | desired.ui_port != host->http_config_port; |
| 447 | if (config_changed && !host->http_retiring) { |
| 448 | host->http_retiring = true; |
| 449 | host->http_retry_at_ms = now_ms; |
| 450 | host->http_retry_delay_ms = HOST_HTTP_RETRY_INITIAL_MS; |
| 451 | } |
| 452 | if (host->http_retiring) { |
| 453 | if (now_ms < host->http_retry_at_ms) { |
| 454 | return; |
| 455 | } |
| 456 | if (!host_http_stop_join_free(host)) { |
| 457 | host_http_schedule_retry(host, now_ms, "server_retire"); |
| 458 | return; |
| 459 | } |
| 460 | host->http_retiring = false; |
| 461 | } |
| 462 | if (config_changed) { |
| 463 | host->http_config_loaded = true; |
| 464 | host->http_config_enabled = desired.ui_enabled; |
| 465 | host->http_config_port = desired.ui_port; |
| 466 | host->http_retry_at_ms = now_ms; |
| 467 | host->http_retry_delay_ms = HOST_HTTP_RETRY_INITIAL_MS; |
| 468 | } |
| 469 | if (!desired.ui_enabled) { |
| 470 | return; |
| 471 | } |
| 472 | if (host->http_started || host->http) { |
| 473 | return; |
| 474 | } |
| 475 | if (!host->http_assets_available) { |
| 476 | if (config_changed) { |
| 477 | cbm_log_warn("ui.no_assets", "hint", "rebuild with: make -f Makefile.cbm cbm-with-ui"); |
| 478 | } |
| 479 | host->http_retry_at_ms = UINT64_MAX; |
| 480 | return; |
| 481 | } |
| 482 | if (now_ms < host->http_retry_at_ms) { |
| 483 | return; |
| 484 | } |
| 485 | |
| 486 | const host_http_ops_t *ops = host->http_ops; |
| 487 | host->http = ops->server_new(ops->context, desired.ui_port); |
| 488 | if (!host->http) { |
| 489 | host_http_schedule_retry(host, now_ms, "server_create"); |
| 490 | return; |
no test coverage detected