mirror of
https://github.com/LostRuins/koboldcpp.git
synced 2026-09-20 01:31:42 +02:00
server: refactor subproc handling (#28555)
* server: refactor subproc handling * fix Windows build * download: keep concurrent downloads of one blob apart Every process writes the same path + .downloadInProgress, so a second download of the same blob finds that file, takes it for its own partial transfer and asks for the bytes after it, which produces a corrupt result. The in-progress file now carries the pid of the process writing it. std::rename also replaces an existing destination on POSIX but fails on Windows, so a download whose blob appeared in the meantime is dropped after every retry and an etag rewrite silently keeps the old value. std::filesystem::rename has the POSIX behaviour everywhere, and the error now carries the reason reported by the system. * Revert "download: keep concurrent downloads of one blob apart" This reverts commit 917b83f149c625527f872fb2cf41289358fa5371. * tests: serialize the router tests that download the same model Parallel workers share one cache, so the two tests fetch the same blob into the same in-progress file and race to rename it. They now take a file lock around the download, like the session fixture does for the preset models. * Revert "tests: serialize the router tests that download the same model" This reverts commit c368a4a98c677938ca87002edb6186ff2c02fd83. --------- Co-authored-by: Pascal <admin@serveurperso.com>
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
@@ -107,27 +108,29 @@ struct server_model_meta {
|
||||
};
|
||||
|
||||
struct server_models_routes;
|
||||
struct server_subproc; // defined in server-models.cpp
|
||||
struct server_lru_sched; // defined in server-models.cpp
|
||||
struct server_monitor; // defined in server-models.cpp
|
||||
|
||||
struct server_models {
|
||||
friend struct server_models_routes;
|
||||
friend struct server_lru_sched;
|
||||
friend struct server_monitor;
|
||||
|
||||
private:
|
||||
struct instance_t {
|
||||
std::shared_ptr<server_subproc> subproc; // shared between main thread and monitoring thread
|
||||
std::thread th;
|
||||
std::shared_ptr<server_subproc> subproc; // shared with the monitor thread
|
||||
server_model_meta meta;
|
||||
int req_count = 0; // number of active proxy requests
|
||||
|
||||
// ask the child to exit (it handles the command on its stdin, see server_child::setup)
|
||||
void request_exit() const;
|
||||
};
|
||||
|
||||
std::mutex mutex;
|
||||
std::condition_variable cv;
|
||||
std::map<std::string, instance_t> mapping;
|
||||
|
||||
// for stopping models
|
||||
std::condition_variable cv_stop;
|
||||
// models asked to stop, still counted as running until the monitor records their exit
|
||||
std::set<std::string> stopping_models;
|
||||
|
||||
// set to true while load_models() is executing a reload; load() will wait until clear
|
||||
@@ -216,9 +219,12 @@ private:
|
||||
// not thread-safe, caller must hold mutex
|
||||
void add_model(server_model_meta && meta);
|
||||
|
||||
// ask the monitoring thread to stop a running instance
|
||||
// ask the monitor to stop a running instance; send_exit is false for a child that was already force-killed
|
||||
// not thread-safe, caller must hold mutex
|
||||
void request_stop(const std::string & name);
|
||||
void request_stop(const std::string & name, bool send_exit = true);
|
||||
|
||||
// called by the monitor once a child exited and was reaped
|
||||
void on_child_exit(const std::string & name, const std::shared_ptr<server_subproc> & proc, server_child_mode mode, int exit_code);
|
||||
|
||||
// notify SSE clients
|
||||
void notify_sse(const std::string & event, const std::string & model_id, const json & data = nullptr);
|
||||
@@ -297,12 +303,16 @@ public:
|
||||
|
||||
// handle message sent from server_child::notify_to_router()
|
||||
// raw input must starts with CMD_CHILD_TO_ROUTER_STATE, followed by a JSON string
|
||||
// this function is not thread-safe, must be called from instance's monitoring thread
|
||||
// called from the monitor thread
|
||||
// payload per state:
|
||||
// state = loading -> payload = {} (TODO: add progress info)
|
||||
// state = ready -> payload = model_info (json), or {} if wakeup from sleeping
|
||||
// state = sleeping -> payload = {}
|
||||
void handle_child_state(const std::string & name, const std::string & raw_input);
|
||||
|
||||
private:
|
||||
// one thread watching every child; keep last, the destructor joins the thread
|
||||
std::unique_ptr<server_monitor> monitor;
|
||||
};
|
||||
|
||||
struct server_child {
|
||||
|
||||
Reference in New Issue
Block a user