diff --git a/image_puller/ImagePuller.h b/image_puller/ImagePuller.h index dd91fcb5a..fec35d311 100644 --- a/image_puller/ImagePuller.h +++ b/image_puller/ImagePuller.h @@ -48,10 +48,12 @@ struct ImagePullerStatistics { class ImagePuller { protected: ThreadSafeFIFO outside_fifo; // assuming 1 file is <1000 files, this should be enough to buffer - // Bounds the bytes of received messages until consumed; size 0: on the heap, bounded by the queues alone + // Holds every received message until it is consumed. The queues count messages, the ring bounds bytes. + // With size 0 there is no ring: messages are held on the heap, bounded by the queues alone. ReceiveRingBuffer ring; - // Bytes republish holds now: capped at a share of the ring, as a slow republish consumer pins all received after + // Bytes republish holds now. Republish keeps the oldest unsent images and the ring is reclaimed in arrival order, + // so a slow republish consumer would pin everything received after them. That is why it is capped at a share of the ring. std::atomic repub_bytes{0}; bool RepubCanHold(size_t bytes) const { return ring.GetCapacity() == 0 || repub_bytes.load() + bytes <= ring.GetCapacity() / 4; diff --git a/image_puller/ZMQImagePuller.cpp b/image_puller/ZMQImagePuller.cpp index 533d392d2..377e88906 100644 --- a/image_puller/ZMQImagePuller.cpp +++ b/image_puller/ZMQImagePuller.cpp @@ -84,7 +84,8 @@ void ZMQImagePuller::PullerThread() { ret.raw = std::shared_ptr(new ReceiveBufferRegion{const_cast(msg->data()), msg->size()}, [msg](ReceiveBufferRegion *r) { delete r; }); } else { - // When the ring is full this waits, and the socket is not read: the sender's send blocks for as long as it waits + // When the ring is full this waits and the socket is not read, so the sender's send blocks. + // The broker's ZeroMQ pusher waits one second, then drops the image, so a ring too small for the writer's stalls costs images. ret.raw = ring.Allocate(msg->size()); if (!ret.raw) { // Stop() - the puller is being disconnected. diff --git a/receiver/JFJochReceiverStream.cpp b/receiver/JFJochReceiverStream.cpp index 7e843b6b0..d673a766c 100644 --- a/receiver/JFJochReceiverStream.cpp +++ b/receiver/JFJochReceiverStream.cpp @@ -256,7 +256,7 @@ void JFJochReceiverStream::AddToEndMessage(EndMessage &message) { message.adu_histogram = end_adu_histogram; } -// With the card summing, an image is many frames. +// The collection is counted in images, not frames. When the card sums frames, one image is many frames. int64_t JFJochReceiverStream::ExpectedImages() const { return experiment.GetImageNum(); } diff --git a/receiver/RugnuxLiveStatus.h b/receiver/RugnuxLiveStatus.h index a73c1ee2d..5c372c286 100644 --- a/receiver/RugnuxLiveStatus.h +++ b/receiver/RugnuxLiveStatus.h @@ -14,7 +14,9 @@ class RugnuxStructure; // RugnuxStructure.h struct ProcessResult; // rugnux/Rugnux.h -// Where the live rugnux run of the last collection is; times in seconds since the first image arrived +// Where the live rugnux run of the last collection is. +// Times come from the image puller (when a message came off the socket) and are in seconds since the first image arrived. +// The START message comes earlier, by start_to_first_image_s. The frame rate is (images_received - 1) / last_image_s. enum class RugnuxLiveState { Idle, Running, Done, Failed, Cancelled, Skipped }; struct RugnuxLiveStep { diff --git a/receiver/RugnuxStructure.h b/receiver/RugnuxStructure.h index d27129d85..39dd82183 100644 --- a/receiver/RugnuxStructure.h +++ b/receiver/RugnuxStructure.h @@ -42,7 +42,9 @@ public: // The coefficients include the anomalous difference map (ANOM/PHANOM): the merge kept the Bijvoet pairs. bool HasAnomalousMap() const; std::string ModelCif() const; - // A CCP4 map sampled every d_min/3, on one unit cell around the model; empty where there are no coefficients + // A CCP4 map sampled every d_min/3, on one unit cell centred on the model. + // Along an axis where the model reaches further than the cell, the map covers the model plus MAP_MARGIN_A instead. + // The mean and RMS in the header are those of the cell. Empty where there are no coefficients. std::string Map(RugnuxMapType type) const; };