HttpResponse#StartStreaming(): release CpuBoundWork

so that /v1/events doesn't have to use IoBoundWorkSlot. IoBoundWorkSlot#~IoBoundWorkSlot() will wait for a free semaphore slot which will be almost immediately released by CpuBoundWork#~CpuBoundWork(). Just releasing the already aquired slot in HttpServerConnection#StartStreaming() is more efficient.
This commit is contained in:
Alexander A. Klimov 2025-08-29 14:52:17 +02:00
parent 87df80d322
commit cc46ab0bc5
4 changed files with 17 additions and 3 deletions

View File

@ -100,8 +100,6 @@ bool EventsHandler::HandleRequest(
EventsSubscriber subscriber (std::move(eventTypes), HttpUtility::GetLastParameter(params, "filter"), l_ApiQuery); EventsSubscriber subscriber (std::move(eventTypes), HttpUtility::GetLastParameter(params, "filter"), l_ApiQuery);
IoBoundWorkSlot dontLockTheIoThread (yc);
response.result(http::status::ok); response.result(http::status::ok);
response.set(http::field::content_type, "application/json"); response.set(http::field::content_type, "application/json");
response.StartStreaming(true); response.StartStreaming(true);

View File

@ -151,6 +151,12 @@ void HttpResponse::Flush(boost::asio::yield_context yc)
void HttpResponse::StartStreaming(bool checkForDisconnect) void HttpResponse::StartStreaming(bool checkForDisconnect)
{ {
auto work (m_CpuBoundWork.lock());
if (work) {
work->Done();
}
ASSERT(body().Size() == 0 && !m_SerializationStarted); ASSERT(body().Size() == 0 && !m_SerializationStarted);
body().Start(); body().Start();
chunked(true); chunked(true);

View File

@ -3,6 +3,7 @@
#pragma once #pragma once
#include "base/dictionary.hpp" #include "base/dictionary.hpp"
#include "base/io-engine.hpp"
#include "base/json.hpp" #include "base/json.hpp"
#include "base/tlsstream.hpp" #include "base/tlsstream.hpp"
#include "remote/apiuser.hpp" #include "remote/apiuser.hpp"
@ -10,6 +11,8 @@
#include "remote/url.hpp" #include "remote/url.hpp"
#include <boost/beast/http.hpp> #include <boost/beast/http.hpp>
#include <boost/version.hpp> #include <boost/version.hpp>
#include <memory>
#include <utility>
namespace icinga { namespace icinga {
@ -217,6 +220,11 @@ public:
*/ */
void Clear(); void Clear();
void SetCpuBoundWork(std::weak_ptr<CpuBoundWork> cbw)
{
m_CpuBoundWork = std::move(cbw);
}
/** /**
* Writes as much of the response as is currently available. * Writes as much of the response as is currently available.
* *
@ -273,6 +281,7 @@ private:
using Serializer = boost::beast::http::response_serializer<HttpResponse::body_type>; using Serializer = boost::beast::http::response_serializer<HttpResponse::body_type>;
Serializer m_Serializer{*this}; Serializer m_Serializer{*this};
bool m_SerializationStarted = false; bool m_SerializationStarted = false;
std::weak_ptr<CpuBoundWork> m_CpuBoundWork;
HttpServerConnection::Ptr m_Server; HttpServerConnection::Ptr m_Server;
Shared<AsioTlsStream>::Ptr m_Stream; Shared<AsioTlsStream>::Ptr m_Stream;

View File

@ -419,9 +419,10 @@ void ProcessRequest(
try { try {
// Cache the elapsed time to acquire a CPU semaphore used to detect extremely heavy workloads. // Cache the elapsed time to acquire a CPU semaphore used to detect extremely heavy workloads.
auto start (std::chrono::steady_clock::now()); auto start (std::chrono::steady_clock::now());
CpuBoundWork handlingRequest (yc); auto handlingRequest (std::make_shared<CpuBoundWork>(yc));
cpuBoundWorkTime = std::chrono::steady_clock::now() - start; cpuBoundWorkTime = std::chrono::steady_clock::now() - start;
response.SetCpuBoundWork(handlingRequest);
HttpHandler::ProcessRequest(waitGroup, request, response, yc); HttpHandler::ProcessRequest(waitGroup, request, response, yc);
response.body().Finish(); response.body().Finish();
} catch (const std::exception& ex) { } catch (const std::exception& ex) {