HttpResponse#StartStreaming(): release CpuBoundWork if checkForDisconnect is true

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-09-15 10:41:48 +02:00
parent 87df80d322
commit a14442aaa3
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);
IoBoundWorkSlot dontLockTheIoThread (yc);
response.result(http::status::ok);
response.set(http::field::content_type, "application/json");
response.StartStreaming(true);

View File

@ -156,6 +156,12 @@ void HttpResponse::StartStreaming(bool checkForDisconnect)
chunked(true);
if (checkForDisconnect) {
auto work (m_CpuBoundWork.lock());
if (work) {
work->Done();
}
ASSERT(m_Server);
m_Server->StartDetectClientSideShutdown();
}

View File

@ -3,6 +3,7 @@
#pragma once
#include "base/dictionary.hpp"
#include "base/io-engine.hpp"
#include "base/json.hpp"
#include "base/tlsstream.hpp"
#include "remote/apiuser.hpp"
@ -10,6 +11,8 @@
#include "remote/url.hpp"
#include <boost/beast/http.hpp>
#include <boost/version.hpp>
#include <memory>
#include <utility>
namespace icinga {
@ -217,6 +220,11 @@ public:
*/
void Clear();
void SetCpuBoundWork(std::weak_ptr<CpuBoundWork> cbw)
{
m_CpuBoundWork = std::move(cbw);
}
/**
* 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>;
Serializer m_Serializer{*this};
bool m_SerializationStarted = false;
std::weak_ptr<CpuBoundWork> m_CpuBoundWork;
HttpServerConnection::Ptr m_Server;
Shared<AsioTlsStream>::Ptr m_Stream;

View File

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