Every image thread took the socket's mutex to add its message, and the thread that cut a batch then
serialised and sent the whole period's images while holding it, so all image threads waited for the
encode. Now the message is copied outside the lock without spots, reflections and image (the metadata
message never carries them), the lock only appends and swaps the batch out, and the batch is serialised
into its own buffer and sent with the lock released. Two batches cut close together can leave in either
order, which the documentation already allows; END stays last.
Two latent faults go with it: a disabled socket (no period) kept every image of the run and sent them
all at END - now it keeps nothing; and the batch buffer was a fixed 20 kB per image, too small for a 2D
azimuthal integration profile - it is now sized from the profile and ADU histogram lengths.
(ported from rc184-2 4147934e6)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HVeDQsU5a8AJUdJPgWevAK
47 lines
1.2 KiB
C++
47 lines
1.2 KiB
C++
// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#ifndef ZMQMETADATASOCKET_H
|
|
#define ZMQMETADATASOCKET_H
|
|
|
|
#include <mutex>
|
|
#include <vector>
|
|
|
|
#include "PreviewCounter.h"
|
|
#include "../common/JFJochMessages.h"
|
|
#include "../common/ZMQWrappers.h"
|
|
|
|
struct ZMQMetadataSettings {
|
|
std::optional<std::chrono::microseconds> period;
|
|
std::string address;
|
|
};
|
|
|
|
class ZMQMetadataSocket {
|
|
mutable std::mutex m;
|
|
|
|
constexpr static uint32_t DefaultSendWatermark = 100;
|
|
|
|
MetadataMessage metadata_message;
|
|
ZMQSocket socket;
|
|
std::vector<uint8_t> buffer; // START and END only, under m
|
|
PreviewCounter counter;
|
|
|
|
bool first_image;
|
|
|
|
void Send(const MetadataMessage &batch);
|
|
public:
|
|
explicit ZMQMetadataSocket(const std::string &addr);
|
|
|
|
ZMQMetadataSocket& Period(const std::optional<std::chrono::microseconds> &period);
|
|
ZMQMetadataSocket& ImportSettings(const ZMQMetadataSettings &settings);
|
|
|
|
void StartDataCollection(const StartMessage &message);
|
|
void AddDataMessage(const DataMessage &msg);
|
|
void EndDataCollection(const EndMessage &message);
|
|
|
|
ZMQMetadataSettings GetSettings();
|
|
std::string GetAddress();
|
|
};
|
|
|
|
#endif //ZMQMETADATASOCKET_H
|