TCP: Implemented ACK return stream, as a feedback channel (to be read properly!)

This commit is contained in:
2026-03-04 12:24:05 +01:00
parent 939bb02ce2
commit a3a986830b
13 changed files with 611 additions and 80 deletions

View File

@@ -20,6 +20,27 @@ StreamWriter::StreamWriter(Logger &in_logger,
max_image_number(0) {
}
void StreamWriter::NotifyTcpAck(TCPFrameType ack_for, bool ok, bool fatal, TCPAckCode code, const std::string &error_text) {
if (!image_puller.SupportsAck())
return;
PullerAckMessage ack;
ack.ack_for = ack_for;
ack.ok = ok;
ack.fatal = fatal;
ack.error_code = code;
ack.error_text = error_text;
ack.run_number = run_number;
ack.socket_number = static_cast<uint32_t>(socket_number);
ack.processed_images = processed_images.load();
if (image_puller_output.cbor && image_puller_output.cbor->data_message)
ack.image_number = image_puller_output.cbor->data_message->number;
if (!image_puller.SendAck(ack))
logger.Warning("Failed to send TCP ACK");
}
void StreamWriter::ProcessStartMessage() {
if (state == StreamWriterState::Finalized)
return; // Should not happen (?)
@@ -28,6 +49,7 @@ void StreamWriter::ProcessStartMessage() {
FinalizeDataCollection();
err = "";
tcp_data_fatal_sent = false;
max_image_number = 0;
@@ -51,11 +73,13 @@ void StreamWriter::ProcessStartMessage() {
image_puller_output.cbor->start_message->file_prefix,
image_puller_output.cbor->start_message->number_of_images);
state = StreamWriterState::Started;
NotifyTcpAck(TCPFrameType::START, true, false, TCPAckCode::None);
} catch (const JFJochException &e) {
logger.ErrorException(e);
logger.Error("Error writing start message - switching to error state");
state = StreamWriterState::Error;
err = e.what();
NotifyTcpAck(TCPFrameType::START, false, true, TCPAckCode::StartFailed, err);
}
}
@@ -108,6 +132,10 @@ void StreamWriter::ProcessDataImage() {
logger.Warning("Error writing image - switching to error state");
state = StreamWriterState::Error;
err = e.what();
if (!tcp_data_fatal_sent) {
tcp_data_fatal_sent = true;
NotifyTcpAck(TCPFrameType::DATA, false, true, TCPAckCode::DataWriteFailed, err);
}
}
break;
case StreamWriterState::Error:
@@ -156,6 +184,11 @@ void StreamWriter::FinalizeDataCollection() {
}
file_writer.reset();
NotifyReceiverOnFinalizedWrite(writer_notification_zmq_addr);
NotifyTcpAck(TCPFrameType::END,
state != StreamWriterState::Error,
state == StreamWriterState::Error,
state == StreamWriterState::Error ? TCPAckCode::EndFailed : TCPAckCode::None,
state == StreamWriterState::Error ? err : "");
logger.Info("Data writing finished");
state = StreamWriterState::Finalized;
}
@@ -168,6 +201,21 @@ void StreamWriter::CollectImages() {
while (run && state != StreamWriterState::Finalized) {
run = WaitForImage();
if (image_puller_output.tcp_msg &&
static_cast<TCPFrameType>(image_puller_output.tcp_msg->header.type) == TCPFrameType::CANCEL) {
logger.Warning("Received TCP CANCEL, finalizing data collection");
if (state != StreamWriterState::Idle && state != StreamWriterState::Finalized)
FinalizeDataCollection();
NotifyTcpAck(TCPFrameType::CANCEL, true, false, TCPAckCode::None);
state = StreamWriterState::Finalized;
continue;
}
if (!image_puller_output.cbor) {
logger.Warning("Missing CBOR payload for non-CANCEL TCP frame");
continue;
}
if (image_puller_output.cbor->start_message)
ProcessStartMessage();
else if (image_puller_output.cbor->calibration)