mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-23 21:22:49 +00:00
feat(ugc): processor=toolbox-blender in the UGC server
The processor setting and toolbox_* settings (Blender, LU-Toolbox- Standalone, add-ons folder, brick and work folders, device, threads, timeout). Models asking for toolbox-blender are made by the Blender worker when it can run, else natively, logged at start, when it changes and per make. /status has the worker's state; --make-model takes toolbox-blender too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -152,6 +152,20 @@ void UgcProcessor::Stop() {
|
||||
if (thread.joinable()) thread.join();
|
||||
}
|
||||
m_Threads.clear(); if (m_FileThread.joinable()) m_FileThread.join();
|
||||
// LU Toolbox's Blender goes with the workers
|
||||
m_Toolbox.Stop();
|
||||
}
|
||||
|
||||
void UgcProcessor::ConfigureToolbox(const UgcToolbox::Config& config) {
|
||||
m_Toolbox.Configure(config);
|
||||
auto problem = UgcToolbox::Problem(config);
|
||||
std::lock_guard lock(m_Mutex);
|
||||
m_ToolboxProblem = std::move(problem);
|
||||
}
|
||||
|
||||
std::string UgcProcessor::ToolboxProblem() const {
|
||||
std::lock_guard lock(m_Mutex);
|
||||
return m_ToolboxProblem;
|
||||
}
|
||||
|
||||
void UgcProcessor::Drain() {
|
||||
@@ -188,6 +202,7 @@ void UgcProcessor::Worker() {
|
||||
while (true) {
|
||||
Job job;
|
||||
UgcJobs::Settings settings;
|
||||
std::string toolboxProblem;
|
||||
int nice = 0;
|
||||
{
|
||||
std::unique_lock lock(m_Mutex);
|
||||
@@ -213,6 +228,7 @@ void UgcProcessor::Worker() {
|
||||
m_MemoryInUse += job.memory;
|
||||
settings = m_Settings;
|
||||
nice = m_Limits.nice;
|
||||
toolboxProblem = m_ToolboxProblem;
|
||||
}
|
||||
if (nice != appliedNice) {
|
||||
ApplyNice(nice);
|
||||
@@ -304,9 +320,19 @@ void UgcProcessor::Worker() {
|
||||
// The processing options staff picked for this make, over the settings (unknown ones: the settings')
|
||||
UgcProcessOptions::Choice choice;
|
||||
if (job.kind == Kind::MODEL && UgcProcessOptions::Parse(job.options, choice)) UgcJobs::ApplyOptions(settings, choice);
|
||||
done.outcome = job.kind == Kind::MODEL
|
||||
? UgcJobs::ProcessModel(job.blob, m_Library, settings, static_cast<uint64_t>(job.id), job.iconValues)
|
||||
: UgcJobs::ProcessModular(job.modular, m_Library.GetResPath(), settings);
|
||||
// LU Toolbox in Blender when it's asked for and can run, else the UGC server's own pipeline (and why)
|
||||
const bool toolbox = job.kind == Kind::MODEL &&
|
||||
UgcToolbox::Resolve(settings.processor, toolboxProblem, done.fallback) == UgcProcessOptions::TOOLBOX_BLENDER;
|
||||
if (toolbox) {
|
||||
done.outcome = UgcJobs::ProcessModelToolbox(job.blob, m_Library, settings, m_Toolbox, static_cast<uint64_t>(job.id), job.iconValues);
|
||||
} else if (job.kind == Kind::MODEL) {
|
||||
done.outcome = UgcJobs::ProcessModel(job.blob, m_Library, settings, static_cast<uint64_t>(job.id), job.iconValues);
|
||||
if (!done.fallback.empty()) {
|
||||
done.outcome.note = "toolbox-blender can't be used (" + done.fallback + "): made natively" + (done.outcome.note.empty() ? "" : "; " + done.outcome.note);
|
||||
}
|
||||
} else {
|
||||
done.outcome = UgcJobs::ProcessModular(job.modular, m_Library.GetResPath(), settings);
|
||||
}
|
||||
}
|
||||
} catch (const UgcThrottle::Cancelled&) {
|
||||
// Stopping: abandoned, not failed; nothing is written or recorded
|
||||
@@ -498,6 +524,9 @@ void UgcProcessor::Record(const Done& done) {
|
||||
if (const auto combo = m_ComboOf.find(done.id); combo != m_ComboOf.end()) Database::Get()->SetModularBuildCombination(done.id, combo->second);
|
||||
}
|
||||
m_Recent.erase({ done.kind, done.id });
|
||||
if (!done.fallback.empty()) {
|
||||
LOG("Model %llu asked for toolbox-blender, which can't be used (%s): made natively", static_cast<unsigned long long>(done.id), done.fallback.c_str());
|
||||
}
|
||||
|
||||
if (done.outcome.empty) {
|
||||
m_Empty++;
|
||||
@@ -727,6 +756,8 @@ nlohmann::json UgcProcessor::Status() const {
|
||||
status["evicted"] = m_Evicted;
|
||||
status["storedBytes"] = m_StoredBytes;
|
||||
status["maxStorageBytes"] = m_Config.maxStorageBytes;
|
||||
// LU Toolbox's Blender (processor=toolbox-blender): whether it runs, what it reported, why it can't be used
|
||||
status["toolbox"] = m_Toolbox.Status();
|
||||
auto& recent = status["recent"] = nlohmann::json::array();
|
||||
for (auto it = m_Log.rbegin(); it != m_Log.rend(); ++it) {
|
||||
recent.push_back({ { "kind", KindName(it->kind) }, { "id", std::to_string(it->id) }, { "ok", it->ok },
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "UgcIconParams.h"
|
||||
#include "UgcJobs.h"
|
||||
#include "UgcStorage.h"
|
||||
#include "UgcToolbox.h"
|
||||
|
||||
/**
|
||||
* The UGC server's queue. The main thread (Update) takes pending rows from the database, gathers each one's input
|
||||
@@ -58,6 +59,12 @@ public:
|
||||
|
||||
// Main thread: new settings and limits (config reload)
|
||||
void Configure(UgcJobs::Settings settings, Limits limits);
|
||||
|
||||
// Main thread: LU Toolbox's Blender settings (processor=toolbox-blender); a running Blender is started again with
|
||||
// them before its next model
|
||||
void ConfigureToolbox(const UgcToolbox::Config& config);
|
||||
// Why toolbox-blender can't be used with the settings given (empty: it can)
|
||||
std::string ToolboxProblem() const;
|
||||
// Waits for the jobs that are running; queued ones are dropped (they stay pending in the database)
|
||||
void Stop();
|
||||
|
||||
@@ -200,6 +207,7 @@ private:
|
||||
bool iconOnly{};
|
||||
double iconChangeMs{}; // an icon drawn again: how much longer it took than the icon made before
|
||||
std::vector<Checksum> checksums; // of the files written that the client downloads as sd0
|
||||
std::string fallback; // toolbox-blender was asked for but can't be used: why (made natively)
|
||||
};
|
||||
|
||||
// Main thread: records the checksums of an item's files (ugc_file_checksums)
|
||||
@@ -229,6 +237,8 @@ private:
|
||||
UgcBricks::BrickLibrary& m_Library;
|
||||
UgcJobs::Settings m_Settings; // guarded by m_Mutex (workers copy it per job)
|
||||
Limits m_Limits; // guarded by m_Mutex
|
||||
UgcToolbox::Worker m_Toolbox; // LU Toolbox's Blender, which the workers take turns on
|
||||
std::string m_ToolboxProblem{ "not configured" }; // guarded by m_Mutex: why toolbox-blender can't be used (UgcToolbox::Problem)
|
||||
|
||||
mutable std::mutex m_Mutex;
|
||||
std::condition_variable m_Wake;
|
||||
|
||||
Reference in New Issue
Block a user