address most problems
This commit is contained in:
parent
216140867e
commit
5369aaa1d6
|
|
@ -10,6 +10,8 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
|
@ -60,7 +62,10 @@ static std::filesystem::path get_server_exec_path() {
|
||||||
#else
|
#else
|
||||||
char path[FILENAME_MAX];
|
char path[FILENAME_MAX];
|
||||||
ssize_t count = readlink("/proc/self/exe", path, FILENAME_MAX);
|
ssize_t count = readlink("/proc/self/exe", path, FILENAME_MAX);
|
||||||
return std::filesystem::path(std::string(path, (count > 0) ? count: 0));
|
if (count <= 0) {
|
||||||
|
throw std::runtime_error("failed to resolve /proc/self/exe");
|
||||||
|
}
|
||||||
|
return std::filesystem::path(std::string(path, count));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -203,22 +208,27 @@ std::vector<server_model_meta> server_models::get_all_meta() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_models::load(const std::string & name) {
|
void server_models::load(const std::string & name) {
|
||||||
auto meta = get_meta(name);
|
std::lock_guard<std::mutex> lk(mutex);
|
||||||
if (!meta.has_value()) {
|
if (mapping.find(name) == mapping.end()) {
|
||||||
throw std::runtime_error("model name=" + name + " is not found");
|
throw std::runtime_error("model name=" + name + " is not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lk(mutex);
|
auto meta = mapping[name].meta;
|
||||||
if (meta->status != SERVER_MODEL_STATUS_FAILED && meta->status != SERVER_MODEL_STATUS_UNLOADED) {
|
if (meta.status != SERVER_MODEL_STATUS_FAILED && meta.status != SERVER_MODEL_STATUS_UNLOADED) {
|
||||||
SRV_INF("model %s is not ready\n", name.c_str());
|
SRV_INF("model %s is not ready\n", name.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prepare new instance info
|
||||||
instance_t inst;
|
instance_t inst;
|
||||||
inst.meta = meta.value();
|
inst.meta = meta;
|
||||||
inst.meta.port = get_free_port();
|
inst.meta.port = get_free_port();
|
||||||
inst.meta.status = SERVER_MODEL_STATUS_LOADING;
|
inst.meta.status = SERVER_MODEL_STATUS_LOADING;
|
||||||
|
|
||||||
|
if (inst.meta.port <= 0) {
|
||||||
|
throw std::runtime_error("failed to get a port number");
|
||||||
|
}
|
||||||
|
|
||||||
inst.subproc = std::make_shared<subprocess_s>();
|
inst.subproc = std::make_shared<subprocess_s>();
|
||||||
{
|
{
|
||||||
std::string exec_path = get_server_exec_path().string();
|
std::string exec_path = get_server_exec_path().string();
|
||||||
|
|
@ -354,17 +364,25 @@ void server_models::wait_until_loaded(const std::string & name) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_models::ensure_model_loaded(const std::string & name) {
|
bool server_models::ensure_model_loaded(const std::string & name) {
|
||||||
auto meta = get_meta(name);
|
auto meta = get_meta(name);
|
||||||
if (!meta.has_value()) {
|
if (!meta.has_value()) {
|
||||||
throw std::runtime_error("model name=" + name + " is not found");
|
throw std::runtime_error("model name=" + name + " is not found");
|
||||||
}
|
}
|
||||||
if (meta->is_active()) {
|
if (meta->is_active()) {
|
||||||
return; // already loaded
|
return false; // already loaded
|
||||||
}
|
}
|
||||||
SRV_INF("model name=%s is not loaded, loading...\n", name.c_str());
|
SRV_INF("model name=%s is not loaded, loading...\n", name.c_str());
|
||||||
load(name);
|
load(name);
|
||||||
wait_until_loaded(name);
|
wait_until_loaded(name);
|
||||||
|
{
|
||||||
|
// check final status
|
||||||
|
meta = get_meta(name);
|
||||||
|
if (!meta.has_value() || meta->status == SERVER_MODEL_STATUS_FAILED) {
|
||||||
|
throw std::runtime_error("model name=" + name + " failed to load");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
server_http_res_ptr server_models::proxy_request(const server_http_req & req, const std::string & method, const std::string & name) {
|
server_http_res_ptr server_models::proxy_request(const server_http_req & req, const std::string & method, const std::string & name) {
|
||||||
|
|
@ -372,7 +390,9 @@ server_http_res_ptr server_models::proxy_request(const server_http_req & req, co
|
||||||
if (!meta.has_value()) {
|
if (!meta.has_value()) {
|
||||||
throw std::runtime_error("model name=" + name + " is not found");
|
throw std::runtime_error("model name=" + name + " is not found");
|
||||||
}
|
}
|
||||||
ensure_model_loaded(name); // TODO: handle failure case
|
if (ensure_model_loaded(name)) {
|
||||||
|
meta = get_meta(name); // refresh meta
|
||||||
|
}
|
||||||
SRV_INF("proxying request to model %s on port %d\n", name.c_str(), meta->port);
|
SRV_INF("proxying request to model %s on port %d\n", name.c_str(), meta->port);
|
||||||
auto proxy = std::make_unique<server_http_proxy>(
|
auto proxy = std::make_unique<server_http_proxy>(
|
||||||
method,
|
method,
|
||||||
|
|
@ -439,11 +459,11 @@ struct pipe_t {
|
||||||
std::atomic<bool> writer_closed{false};
|
std::atomic<bool> writer_closed{false};
|
||||||
std::atomic<bool> reader_closed{false};
|
std::atomic<bool> reader_closed{false};
|
||||||
void close_write() {
|
void close_write() {
|
||||||
writer_closed.store(true);
|
writer_closed.store(true, std::memory_order_relaxed);
|
||||||
cv.notify_all();
|
cv.notify_all();
|
||||||
}
|
}
|
||||||
void close_read() {
|
void close_read() {
|
||||||
reader_closed.store(true);
|
reader_closed.store(true, std::memory_order_relaxed);
|
||||||
cv.notify_all();
|
cv.notify_all();
|
||||||
}
|
}
|
||||||
bool read(T & output, const std::function<bool()> & should_stop) {
|
bool read(T & output, const std::function<bool()> & should_stop) {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* state diagram:
|
* state diagram:
|
||||||
*
|
*
|
||||||
* UNLOADED ──► LOADING ──► LOADED
|
* UNLOADED ──► LOADING ──► LOADED
|
||||||
* ▲ │
|
* ▲ │
|
||||||
* │ │
|
* │ │
|
||||||
|
|
@ -105,7 +105,8 @@ public:
|
||||||
void wait_until_loaded(const std::string & name);
|
void wait_until_loaded(const std::string & name);
|
||||||
|
|
||||||
// load the model if not loaded, otherwise do nothing
|
// load the model if not loaded, otherwise do nothing
|
||||||
void ensure_model_loaded(const std::string & name);
|
// return false if model is already loaded; return true otherwise (meta may need to be refreshed)
|
||||||
|
bool ensure_model_loaded(const std::string & name);
|
||||||
|
|
||||||
// proxy an HTTP request to the model instance
|
// proxy an HTTP request to the model instance
|
||||||
server_http_res_ptr proxy_request(const server_http_req & req, const std::string & method, const std::string & name);
|
server_http_res_ptr proxy_request(const server_http_req & req, const std::string & method, const std::string & name);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue