server : wrap around the "id_slot" parameter (#19207)

* server : wrap around the "id_slot" parameter

* cont : minor
This commit is contained in:
Georgi Gerganov 2026-01-30 19:46:10 +02:00 committed by GitHub
parent 13f3ebfae1
commit bbada8bfb9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 19 deletions

View File

@ -155,7 +155,7 @@ struct server_slot {
double t_prompt_processing; // ms double t_prompt_processing; // ms
double t_token_generation; // ms double t_token_generation; // ms
std::function<void(int /* slot_id */)> callback_on_release; std::function<void(int /* id_slot */)> callback_on_release;
// Speculative decoding stats // Speculative decoding stats
int32_t n_draft_total = 0; // Total draft tokens generated int32_t n_draft_total = 0; // Total draft tokens generated
@ -767,8 +767,8 @@ private:
SLT_INF(slot, "new slot, n_ctx = %d\n", slot.n_ctx); SLT_INF(slot, "new slot, n_ctx = %d\n", slot.n_ctx);
slot.callback_on_release = [this](int slot_id) { slot.callback_on_release = [this](int id_slot) {
queue_tasks.pop_deferred_task(slot_id); queue_tasks.pop_deferred_task(id_slot);
}; };
slot.reset(); slot.reset();
@ -896,6 +896,9 @@ private:
} }
server_slot * get_slot_by_id(int id_slot) { server_slot * get_slot_by_id(int id_slot) {
// note: allow id_slot to be out of bounds (wrap around)
id_slot = id_slot % slots.size();
for (server_slot & slot : slots) { for (server_slot & slot : slots) {
if (slot.id == id_slot) { if (slot.id == id_slot) {
return &slot; return &slot;
@ -1765,7 +1768,7 @@ private:
break; break;
} }
int id_slot = task.slot_action.slot_id; const int id_slot = task.slot_action.id_slot;
server_slot * slot = get_slot_by_id(id_slot); server_slot * slot = get_slot_by_id(id_slot);
if (slot == nullptr) { if (slot == nullptr) {
send_error(task, "Invalid slot ID", ERROR_TYPE_INVALID_REQUEST); send_error(task, "Invalid slot ID", ERROR_TYPE_INVALID_REQUEST);
@ -1803,7 +1806,7 @@ private:
case SERVER_TASK_TYPE_SLOT_RESTORE: case SERVER_TASK_TYPE_SLOT_RESTORE:
{ {
if (!check_no_mtmd(task.id)) break; if (!check_no_mtmd(task.id)) break;
int id_slot = task.slot_action.slot_id; const int id_slot = task.slot_action.id_slot;
server_slot * slot = get_slot_by_id(id_slot); server_slot * slot = get_slot_by_id(id_slot);
if (slot == nullptr) { if (slot == nullptr) {
send_error(task, "Invalid slot ID", ERROR_TYPE_INVALID_REQUEST); send_error(task, "Invalid slot ID", ERROR_TYPE_INVALID_REQUEST);
@ -1852,7 +1855,7 @@ private:
if (!check_no_mtmd(task.id)) { if (!check_no_mtmd(task.id)) {
break; break;
} }
int id_slot = task.slot_action.slot_id; const int id_slot = task.slot_action.id_slot;
server_slot * slot = get_slot_by_id(id_slot); server_slot * slot = get_slot_by_id(id_slot);
if (slot == nullptr) { if (slot == nullptr) {
send_error(task, "Invalid slot ID", ERROR_TYPE_INVALID_REQUEST); send_error(task, "Invalid slot ID", ERROR_TYPE_INVALID_REQUEST);
@ -3317,7 +3320,7 @@ void server_routes::init_routes() {
} }
// TODO: get rid of this dynamic_cast // TODO: get rid of this dynamic_cast
auto res_task = dynamic_cast<server_task_result_metrics*>(result.get()); auto * res_task = dynamic_cast<server_task_result_metrics*>(result.get());
GGML_ASSERT(res_task != nullptr); GGML_ASSERT(res_task != nullptr);
// optionally return "fail_on_no_slot" error // optionally return "fail_on_no_slot" error
@ -3340,8 +3343,8 @@ void server_routes::init_routes() {
} }
std::string id_slot_str = req.get_param("id_slot"); std::string id_slot_str = req.get_param("id_slot");
int id_slot;
int id_slot;
try { try {
id_slot = std::stoi(id_slot_str); id_slot = std::stoi(id_slot_str);
} catch (const std::exception &) { } catch (const std::exception &) {
@ -3353,14 +3356,16 @@ void server_routes::init_routes() {
if (action == "save") { if (action == "save") {
return handle_slots_save(req, id_slot); return handle_slots_save(req, id_slot);
} else if (action == "restore") {
return handle_slots_restore(req, id_slot);
} else if (action == "erase") {
return handle_slots_erase(req, id_slot);
} else {
res->error(format_error_response("Invalid action", ERROR_TYPE_INVALID_REQUEST));
return res;
} }
if (action == "restore") {
return handle_slots_restore(req, id_slot);
}
if (action == "erase") {
return handle_slots_erase(req, id_slot);
}
res->error(format_error_response("Invalid action", ERROR_TYPE_INVALID_REQUEST));
return res;
}; };
this->get_props = [this](const server_http_req &) { this->get_props = [this](const server_http_req &) {
@ -3903,7 +3908,7 @@ std::unique_ptr<server_res_generator> server_routes::handle_slots_save(const ser
{ {
server_task task(SERVER_TASK_TYPE_SLOT_SAVE); server_task task(SERVER_TASK_TYPE_SLOT_SAVE);
task.id = rd.get_new_id(); task.id = rd.get_new_id();
task.slot_action.slot_id = id_slot; task.slot_action.id_slot = id_slot;
task.slot_action.filename = filename; task.slot_action.filename = filename;
task.slot_action.filepath = filepath; task.slot_action.filepath = filepath;
rd.post_task(std::move(task)); rd.post_task(std::move(task));
@ -3939,7 +3944,7 @@ std::unique_ptr<server_res_generator> server_routes::handle_slots_restore(const
{ {
server_task task(SERVER_TASK_TYPE_SLOT_RESTORE); server_task task(SERVER_TASK_TYPE_SLOT_RESTORE);
task.id = rd.get_new_id(); task.id = rd.get_new_id();
task.slot_action.slot_id = id_slot; task.slot_action.id_slot = id_slot;
task.slot_action.filename = filename; task.slot_action.filename = filename;
task.slot_action.filepath = filepath; task.slot_action.filepath = filepath;
rd.post_task(std::move(task)); rd.post_task(std::move(task));
@ -3968,7 +3973,7 @@ std::unique_ptr<server_res_generator> server_routes::handle_slots_erase(const se
{ {
server_task task(SERVER_TASK_TYPE_SLOT_ERASE); server_task task(SERVER_TASK_TYPE_SLOT_ERASE);
task.id = rd.get_new_id(); task.id = rd.get_new_id();
task.slot_action.slot_id = id_slot; task.slot_action.id_slot = id_slot;
rd.post_task(std::move(task)); rd.post_task(std::move(task));
} }

View File

@ -153,7 +153,7 @@ struct server_task {
// used by SERVER_TASK_TYPE_SLOT_SAVE, SERVER_TASK_TYPE_SLOT_RESTORE, SERVER_TASK_TYPE_SLOT_ERASE // used by SERVER_TASK_TYPE_SLOT_SAVE, SERVER_TASK_TYPE_SLOT_RESTORE, SERVER_TASK_TYPE_SLOT_ERASE
struct slot_action { struct slot_action {
int slot_id; int id_slot;
std::string filename; std::string filename;
std::string filepath; std::string filepath;
}; };