Files
DarkflameServer/dDashboardServer/routes/Workers.cpp
Aaron Kimbrell 17b9479c0e feat(dashboard): every request and page gets game text in the viewer's language
The dashboard loads every language in the client's locale; each request
runs in the viewer's language (Workers::Reply carries it to the worker),
templates get game.* and phrase()/zone_name(), scripts get GameText.* on
<body data-game>, and the user menu picks the game text language.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 22:07:46 -05:00

57 lines
1.7 KiB
C++

#include "Workers.h"
#include <algorithm>
#include <exception>
#include <thread>
#include "GameText.h"
#include "RouteUtils.h"
#include "Web.h"
#include "Game.h"
#include "Logger.h"
#include "dConfig.h"
namespace {
WorkerPool g_Pool;
}
namespace Workers {
void Start() {
auto threads = Game::config ? Game::config->GetValue<uint32_t>("scenery_workers", 0) : 0;
if (threads == 0) threads = static_cast<uint32_t>(WorkerPool::DefaultThreads(std::thread::hardware_concurrency()));
threads = std::clamp<uint32_t>(threads, 2, 16);
// Work ahead of time (converting a zone's models) never takes more than half of the threads besides the fast lane
g_Pool.Start(threads, std::max<size_t>(1, (threads - 1) / 2));
LOG("Dashboard worker threads: %u", threads);
}
void Stop() {
g_Pool.Stop();
}
WorkerPool& Pool() {
return g_Pool;
}
void Reply(HTTPReply& reply, const HTTPContext& context, bool ready, std::function<void(HTTPReply&)> fill, WorkerPool::ePriority priority) {
if (ready || !g_Pool.Running()) return fill(reply);
const auto deferred = Web::Defer(reply, context);
const auto path = context.path;
// The worker writes game text in the viewer's language too
g_Pool.Submit(priority, [deferred, path, language = GameText::Language(), fill = std::move(fill)] {
if (deferred.Cancelled()) return;
const GameText::LanguageScope scope(language);
HTTPReply out;
try {
fill(out);
} catch (const std::exception& ex) {
LOG("Error handling GET %s: %s", path.c_str(), ex.what());
out = HTTPReply{};
RouteUtils::JsonError(out, eHTTPStatusCode::INTERNAL_SERVER_ERROR, "Internal server error");
}
deferred.Send(std::move(out));
});
}
}