feat: wire sse_client_cpp_core for live updates from /api/boards/issues/stream
This commit is contained in:
@@ -6,12 +6,16 @@
|
||||
#include "core/panel_menu.h"
|
||||
#include "core/icons_tabler.h"
|
||||
#include "core/logger.h"
|
||||
#include "core/sse_client.h"
|
||||
#include "panels.h"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
static bool g_show_board = true;
|
||||
static bool g_show_calendar = true;
|
||||
@@ -22,6 +26,11 @@ static bool g_show_dod = true;
|
||||
|
||||
static kanban_cpp::AppState g_state;
|
||||
|
||||
// SSE client: receives push notifications from the backend stream so the
|
||||
// board updates without polling. Lifetime tied to main() — stop() before
|
||||
// returning so the worker thread joins cleanly.
|
||||
static fn_sse::Client g_sse_client;
|
||||
|
||||
static void render() {
|
||||
if (g_show_board) kanban_cpp::draw_board (g_state, &g_show_board);
|
||||
if (g_show_calendar) kanban_cpp::draw_calendar (g_state, &g_show_calendar);
|
||||
@@ -66,8 +75,35 @@ int main(int argc, char** argv) {
|
||||
cfg.panels = panels;
|
||||
cfg.panel_count = sizeof(panels) / sizeof(panels[0]);
|
||||
|
||||
// First refresh on startup (best-effort; failure surfaces in the Board).
|
||||
kanban_cpp::refresh_data(g_state);
|
||||
// First refresh on startup en thread separado: no bloquea primer frame
|
||||
// si el backend :8403 esta caido (timeout HTTP ~9s).
|
||||
std::thread([](){ kanban_cpp::refresh_data(g_state); }).detach();
|
||||
|
||||
return fn::run_app(cfg, render);
|
||||
// SSE live updates: arranca tras 500ms para no competir con el primer
|
||||
// refresh inicial. Auto-reconecta con backoff si el endpoint no existe
|
||||
// aun o si el backend cae — NUNCA crashea el frame.
|
||||
std::thread([](){
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
fn_sse::Config sse_cfg;
|
||||
sse_cfg.url = g_state.cfg.base_url + "/api/boards/issues/stream";
|
||||
sse_cfg.auto_reconnect = true;
|
||||
|
||||
g_sse_client.start(sse_cfg,
|
||||
// on_event: cualquier evento dispara un refresh asincrono.
|
||||
[](const fn_sse::Event& /*ev*/) {
|
||||
std::thread([](){ kanban_cpp::refresh_data(g_state); }).detach();
|
||||
},
|
||||
// on_status: actualiza el badge UI bajo mutex.
|
||||
[](const std::string& status) {
|
||||
std::lock_guard<std::mutex> lock(g_state.mu);
|
||||
g_state.sse_status = status;
|
||||
});
|
||||
}).detach();
|
||||
|
||||
int rc = fn::run_app(cfg, render);
|
||||
|
||||
// Kill SSE worker antes de salir — orden importa para evitar dangling
|
||||
// thread storage cuando se destruyen los globales.
|
||||
g_sse_client.stop();
|
||||
return rc;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user