Outline commit pipeline

This commit is contained in:
2025-09-03 23:43:03 -04:00
parent b2ffe3bfab
commit 9272048108
2 changed files with 231 additions and 75 deletions

View File

@@ -64,6 +64,8 @@ struct HttpConnectionState {
std::unique_ptr<JsonCommitRequestParser> commit_parser;
std::unique_ptr<CommitRequest> commit_request;
bool parsing_commit = false;
bool basic_validation_passed =
false; // Set to true if basic validation passes
explicit HttpConnectionState(ArenaAllocator &arena);
};
@@ -74,69 +76,52 @@ struct HttpConnectionState {
*/
struct HttpHandler : ConnectionHandler {
HttpHandler() {
finalStageThreads.emplace_back([this]() {
pthread_setname_np(pthread_self(), "stage-1-0");
// Stage 0: Version assignment and precondition validation thread
validationThread = std::thread{[this]() {
pthread_setname_np(pthread_self(), "txn-validate");
for (;;) {
auto guard = pipeline.acquire<1, 0>();
for (auto it = guard.batch.begin(); it != guard.batch.end(); ++it) {
if ((it.index() % 2) == 0) { // Thread 0 handles even indices
auto &c = *it;
if (!c) {
return;
}
auto *state = static_cast<HttpConnectionState *>(c->user_data);
TRACE_EVENT("http", "release",
perfetto::Flow::Global(state->request_id));
Server::release_back_to_server(std::move(c));
}
auto guard = commitPipeline.acquire<0, 0>();
if (process_validation_batch(guard.batch)) {
return; // Shutdown signal received
}
}
});
finalStageThreads.emplace_back([this]() {
pthread_setname_np(pthread_self(), "stage-1-1");
}};
// Stage 1: Transaction persistence and subscriber streaming thread
persistenceThread = std::thread{[this]() {
pthread_setname_np(pthread_self(), "txn-persist");
for (;;) {
auto guard = pipeline.acquire<1, 1>();
for (auto it = guard.batch.begin(); it != guard.batch.end(); ++it) {
if ((it.index() % 2) == 1) { // Thread 1 handles odd indices
auto &c = *it;
if (!c) {
return;
}
auto *state = static_cast<HttpConnectionState *>(c->user_data);
TRACE_EVENT("http", "release",
perfetto::Flow::Global(state->request_id));
Server::release_back_to_server(std::move(c));
}
auto guard = commitPipeline.acquire<1, 0>();
if (process_persistence_batch(guard.batch)) {
return; // Shutdown signal received
}
}
});
stage0Thread = std::thread{[this]() {
pthread_setname_np(pthread_self(), "stage-0");
int nulls = 0;
}};
// Stage 2: Connection return to server thread
releaseThread = std::thread{[this]() {
pthread_setname_np(pthread_self(), "txn-release");
for (;;) {
auto guard = pipeline.acquire<0, 0>(1);
for (auto &c : guard.batch) {
nulls += !c;
if (nulls == 2) {
return;
}
for (volatile int i = 0; i < loop_iterations; i = i + 1)
;
auto guard = commitPipeline.acquire<2, 0>();
if (process_release_batch(guard.batch)) {
return; // Shutdown signal received
}
}
}};
}
~HttpHandler() {
// Send shutdown signals to all pipeline stages
{
auto guard = pipeline.push(2, true);
auto guard = commitPipeline.push(3, true);
for (auto &c : guard.batch) {
c = {};
c = {}; // null connection signals shutdown
}
}
stage0Thread.join();
for (auto &thread : finalStageThreads) {
thread.join();
}
// Join all pipeline threads
validationThread.join();
persistenceThread.join();
releaseThread.join();
}
void on_connection_established(Connection &conn) override;
@@ -162,11 +147,24 @@ struct HttpHandler : ConnectionHandler {
private:
static constexpr int lg_size = 16;
// Main commit processing pipeline: validation -> persistence -> release
StaticThreadPipeline<std::unique_ptr<Connection>,
WaitStrategy::WaitIfUpstreamIdle, 1, 2>
pipeline{lg_size};
std::thread stage0Thread;
std::vector<std::thread> finalStageThreads;
WaitStrategy::WaitIfUpstreamIdle, 1, 1, 1>
commitPipeline{lg_size};
// Pipeline stage threads
std::thread validationThread;
std::thread persistenceThread;
std::thread releaseThread;
// Pipeline stage processing methods (batch-based)
using BatchType =
StaticThreadPipeline<std::unique_ptr<Connection>,
WaitStrategy::WaitIfUpstreamIdle, 1, 1, 1>::Batch;
bool process_validation_batch(BatchType &batch);
bool process_persistence_batch(BatchType &batch);
bool process_release_batch(BatchType &batch);
// Route handlers
void handleGetVersion(Connection &conn, const HttpConnectionState &state);