cluster/zeromq: Rework lambdas to member functions

This commit is contained in:
Arne Welzel 2025-07-21 14:45:18 +02:00
parent 5dc4586b70
commit 85d5dda028
2 changed files with 134 additions and 131 deletions

View file

@ -444,36 +444,12 @@ bool ZeroMQBackend::DoPublishLogWrites(const logging::detail::LogWriteHeader& he
return true; return true;
} }
void ZeroMQBackend::Run() { // Forward messages from the inprocess bridge.
char name[4 + 2 + 16 + 1]{}; // zmq-0x<8byte pointer in hex><nul> //
snprintf(name, sizeof(name), "zmq-%p", this); // Either it's 2 parts (tag and payload) for controlling subscriptions
util::detail::set_thread_name(name); // or terminating the thread, or it is 4 parts in which case all the parts
ZEROMQ_DEBUG_THREAD_PRINTF(DebugFlag::THREAD, "Thread starting (%p)\n", this); // are forwarded to the XPUB socket directly for publishing.
void ZeroMQBackend::HandleInprocMessages(std::vector<MultipartMessage>& msgs) {
using MultipartMessage = std::vector<zmq::message_t>;
auto HandleLogMessages = [this](const std::vector<MultipartMessage>& msgs) {
for ( const auto& msg : msgs ) {
// sender, format, type, payload
if ( msg.size() != 4 ) {
ZEROMQ_THREAD_PRINTF("log: error: expected 4 parts, have %zu!\n", msg.size());
continue;
}
byte_buffer payload{msg[3].data<std::byte>(), msg[3].data<std::byte>() + msg[3].size()};
LogMessage lm{.format = std::string(msg[2].data<const char>(), msg[2].size()),
.payload = std::move(payload)};
QueueForProcessing(std::move(lm));
}
};
auto HandleInprocMessages = [this](std::vector<MultipartMessage>& msgs) {
// Forward messages from the inprocess bridge.
//
// Either it's 2 parts (tag and payload) for controlling subscriptions
// or terminating the thread, or it is 4 parts in which case all the parts
// are forwarded to the XPUB socket directly for publishing.
for ( auto& msg : msgs ) { for ( auto& msg : msgs ) {
if ( msg.size() == 2 ) { if ( msg.size() == 2 ) {
InprocTag tag = msg[0].data<InprocTag>()[0]; InprocTag tag = msg[0].data<InprocTag>()[0];
@ -520,8 +496,7 @@ void ZeroMQBackend::Run() {
try { try {
// We sent non-blocking above so we are able to observe and report stalls // We sent non-blocking above so we are able to observe and report stalls
// in a metric. Now that we have done that switch to blocking send. // in a metric. Now that we have done that switch to blocking send.
zmq::send_flags block_flags = zmq::send_flags block_flags = zmq::send_flags::none | (flags & zmq::send_flags::sndmore);
zmq::send_flags::none | (flags & zmq::send_flags::sndmore);
result = xpub.send(part, block_flags); result = xpub.send(part, block_flags);
} catch ( zmq::error_t& err ) { } catch ( zmq::error_t& err ) {
if ( err.num() == ETERM ) if ( err.num() == ETERM )
@ -540,9 +515,24 @@ void ZeroMQBackend::Run() {
ZEROMQ_THREAD_PRINTF("inproc: error: expected 1 or 4 parts, have %zu!\n", msg.size()); ZEROMQ_THREAD_PRINTF("inproc: error: expected 1 or 4 parts, have %zu!\n", msg.size());
} }
} }
}; }
auto HandleXPubMessages = [this](const std::vector<MultipartMessage>& msgs) { void ZeroMQBackend::HandleLogMessages(const std::vector<MultipartMessage>& msgs) {
for ( const auto& msg : msgs ) {
// sender, format, type, payload
if ( msg.size() != 4 ) {
ZEROMQ_THREAD_PRINTF("log: error: expected 4 parts, have %zu!\n", msg.size());
continue;
}
byte_buffer payload{msg[3].data<std::byte>(), msg[3].data<std::byte>() + msg[3].size()};
LogMessage lm{.format = std::string(msg[2].data<const char>(), msg[2].size()), .payload = std::move(payload)};
QueueForProcessing(std::move(lm));
}
}
void ZeroMQBackend::HandleXPubMessages(const std::vector<MultipartMessage>& msgs) {
for ( const auto& msg : msgs ) { for ( const auto& msg : msgs ) {
if ( msg.size() != 1 ) { if ( msg.size() != 1 ) {
ZEROMQ_THREAD_PRINTF("xpub: error: expected 1 part, have %zu!\n", msg.size()); ZEROMQ_THREAD_PRINTF("xpub: error: expected 1 part, have %zu!\n", msg.size());
@ -571,9 +561,9 @@ void ZeroMQBackend::Run() {
QueueForProcessing(std::move(qm)); QueueForProcessing(std::move(qm));
} }
} }
}; }
auto HandleXSubMessages = [this](const std::vector<MultipartMessage>& msgs) { void ZeroMQBackend::HandleXSubMessages(const std::vector<MultipartMessage>& msgs) {
for ( const auto& msg : msgs ) { for ( const auto& msg : msgs ) {
if ( msg.size() != 4 ) { if ( msg.size() != 4 ) {
ZEROMQ_THREAD_PRINTF("xsub: error: expected 4 parts, have %zu!\n", msg.size()); ZEROMQ_THREAD_PRINTF("xsub: error: expected 4 parts, have %zu!\n", msg.size());
@ -592,7 +582,13 @@ void ZeroMQBackend::Run() {
QueueForProcessing(std::move(em)); QueueForProcessing(std::move(em));
} }
}; }
void ZeroMQBackend::Run() {
char name[4 + 2 + 16 + 1]{}; // zmq-0x<8byte pointer in hex><nul>
snprintf(name, sizeof(name), "zmq-%p", this);
util::detail::set_thread_name(name);
ZEROMQ_DEBUG_THREAD_PRINTF(DebugFlag::THREAD, "Thread starting (%p)\n", this);
struct SocketInfo { struct SocketInfo {
zmq::socket_ref socket; zmq::socket_ref socket;
@ -601,10 +597,10 @@ void ZeroMQBackend::Run() {
}; };
std::vector<SocketInfo> sockets = { std::vector<SocketInfo> sockets = {
{.socket = child_inproc, .name = "inproc", .handler = HandleInprocMessages}, {.socket = child_inproc, .name = "inproc", .handler = [this](auto& msgs) { HandleInprocMessages(msgs); }},
{.socket = xpub, .name = "xpub", .handler = HandleXPubMessages}, {.socket = xpub, .name = "xpub", .handler = [this](const auto& msgs) { HandleXPubMessages(msgs); }},
{.socket = xsub, .name = "xsub", .handler = HandleXSubMessages}, {.socket = xsub, .name = "xsub", .handler = [this](const auto& msgs) { HandleXSubMessages(msgs); }},
{.socket = log_pull, .name = "log_pull", .handler = HandleLogMessages}, {.socket = log_pull, .name = "log_pull", .handler = [this](const auto& msgs) { HandleLogMessages(msgs); }},
}; };
// Called when Run() terminates. // Called when Run() terminates.

View file

@ -73,6 +73,13 @@ private:
void DoReadyToPublishCallback(ReadyCallback cb) override; void DoReadyToPublishCallback(ReadyCallback cb) override;
// Inner thread helper methods.
using MultipartMessage = std::vector<zmq::message_t>;
void HandleInprocMessages(std::vector<MultipartMessage>& msgs);
void HandleLogMessages(const std::vector<MultipartMessage>& msgs);
void HandleXPubMessages(const std::vector<MultipartMessage>& msgs);
void HandleXSubMessages(const std::vector<MultipartMessage>& msgs);
// Script level variables. // Script level variables.
std::string connect_xsub_endpoint; std::string connect_xsub_endpoint;
std::string connect_xpub_endpoint; std::string connect_xpub_endpoint;