Add an index to thread pipeline iterators for load balancing

This commit is contained in:
2025-08-22 16:32:48 -04:00
parent f43e623a7e
commit 12d4289568
6 changed files with 96 additions and 52 deletions

View File

@@ -61,33 +61,46 @@ struct HttpConnectionState {
* Supports the WeaselDB REST API endpoints with enum-based routing.
*/
class HttpHandler : public ConnectionHandler {
ThreadPipeline<std::unique_ptr<Connection>> ok_pipeline{10, {1}};
std::thread ok_thread{[this]() {
pthread_setname_np(pthread_self(), "stage-0");
for (;;) {
auto guard = ok_pipeline.acquire(0, 0);
for (auto &c : guard.batch) {
if (!c) {
return;
}
auto *state = static_cast<HttpConnectionState *>(c->user_data);
TRACE_EVENT("http", "pipeline thread",
perfetto::Flow::Global(state->request_id));
Server::releaseBackToServer(std::move(c));
}
}
}};
static constexpr int kFinalStageThreads = 2;
static constexpr int kLogSize = 12;
ThreadPipeline<std::unique_ptr<Connection>> pipeline{kLogSize,
{kFinalStageThreads}};
std::vector<std::thread> finalStageThreads;
public:
HttpHandler() = default;
HttpHandler() {
for (int threadId = 0; threadId < kFinalStageThreads; ++threadId) {
finalStageThreads.emplace_back([this, threadId]() {
pthread_setname_np(pthread_self(),
("stage-0-" + std::to_string(threadId)).c_str());
for (;;) {
auto guard = pipeline.acquire(0, threadId);
for (auto it = guard.batch.begin(); it != guard.batch.end(); ++it) {
if ((it.index() % kFinalStageThreads) == threadId) {
auto &c = *it;
if (!c) {
return;
}
auto *state = static_cast<HttpConnectionState *>(c->user_data);
TRACE_EVENT("http", "pipeline thread",
perfetto::Flow::Global(state->request_id));
Server::releaseBackToServer(std::move(c));
}
}
}
});
}
}
~HttpHandler() {
{
auto guard = ok_pipeline.push(1, true);
auto guard = pipeline.push(kFinalStageThreads, true);
for (auto &c : guard.batch) {
c = {};
}
}
ok_thread.join();
for (auto &thread : finalStageThreads) {
thread.join();
}
}
void on_connection_established(Connection &conn) override;
@@ -95,6 +108,7 @@ public:
void on_data_arrived(std::string_view data,
std::unique_ptr<Connection> &conn_ptr) override;
void on_write_progress(std::unique_ptr<Connection> &conn_ptr) override;
void on_post_batch(std::span<std::unique_ptr<Connection>> /*batch*/) override;
// Route parsing (public for testing)
static HttpRoute parseRoute(std::string_view method, std::string_view url);