Commit 883bce3a authored by jan.koester's avatar jan.koester
Browse files

test

parent c75a2e7f
Loading
Loading
Loading
Loading
+26 −0
Changes for editor/src/webedit_api.cpp: 26 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@
#include <mutex>
#include <iterator>
#include <cstdint>
#include <thread>

#include <htmlpp/html.h>
#include <httppp/exception.h>
@@ -3645,6 +3646,31 @@ json_object *webedit::Api::callAiTool(const std::string &sessionid, const std::s

void webedit::Api::handleAiPrompt(libhttppp::HttpRequest &curreq,
                                   const std::string &sessionid) {
    // Admission control: this handler can block its worker thread for
    // minutes if the AI backend is slow/stuck (see kMaxAiToolRounds's
    // per-round connect/read timeouts below). The server's worker pool is
    // small and fixed-size (roughly one per CPU core) and shared by every
    // route, so letting unbounded concurrent AI requests pile up can starve
    // completely unrelated endpoints. Reject early instead of queuing up
    // behind an already-stuck request.
    static const int kMaxConcurrentAiRequests = []() {
        unsigned hw = std::thread::hardware_concurrency();
        return (std::max)(1, static_cast<int>(hw / 2));
    }();

    struct AiRequestGuard {
        std::atomic<int> &counter;
        ~AiRequestGuard() { counter.fetch_sub(1, std::memory_order_relaxed); }
    };

    if (_activeAiRequests.fetch_add(1, std::memory_order_relaxed) >= kMaxConcurrentAiRequests) {
        _activeAiRequests.fetch_sub(1, std::memory_order_relaxed);
        sendJsonError(curreq, 429,
            "Zu viele gleichzeitige KI-Anfragen -- bitte kurz warten und erneut versuchen.");
        return;
    }
    AiRequestGuard aiRequestGuard{_activeAiRequests};

    std::string body = getRequestBody(curreq);
    json_object *req = json_tokener_parse(body.c_str());
    if (!req) {
+12 −0
Changes for editor/src/webedit_api.h: 12 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <memory>
#include <mutex>
#include <map>
#include <atomic>
#include <stdexcept>

#include <json-c/json.h>
@@ -212,6 +213,17 @@ namespace webedit {
        std::map<std::string, ConnSession> _connSessions;
        std::string _activeConnId; // most recently connected connId (guarded by _connSessionMtx)

        // handleAiPrompt can block its worker thread for a long time (up to
        // the AI backend's read/connect timeout) if the backend is slow or
        // stuck. The server's worker pool is a small, fixed size (roughly
        // one per CPU core) shared by every route, so enough concurrent
        // stuck AI requests can starve the whole server -- including
        // completely unrelated endpoints. This caps how many /api/ai/prompt
        // requests may occupy a worker at once; beyond that, new requests
        // are rejected immediately with a clear error instead of queuing
        // up behind an already-stuck one.
        std::atomic<int> _activeAiRequests{0};

        // Document section list (for section_select widget field)
        void handleListDocumentSections(libhttppp::HttpRequest &curreq, const std::string &sessionid);