Outline commit pipeline
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user