broker: initialize and start clear the last collection's live rugnux status
/rugnux/status kept answering with the previous collection's rugnux run after POST /initialize, and also after a /start whose collection does not run rugnux - the latter under the new run's tokens. RugnuxLiveStatus gets a Clear(), called from JFJochReceiverService::ClearResults(), which /start already uses to drop the previous run's status, plots and buffered images before the tokens change. Initialize now calls ClearResults() instead of ClearImageBuffer(), so a fresh start also drops the previous run's receiver status and plots. Authentication: every rugnux endpoint (GET/PUT /config/rugnux, PUT/DELETE /config/rugnux/model, GET /rugnux/status) was already in the broker's bearer-protected set and carries bearerAuth in jfjoch_api.yaml; the HTTP auth test now checks all five. The yaml descriptions of /initialize and rugnux_live_status say so; the C++ model and frontend client are regenerated (comments only). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4
This commit is contained in:
1 parent
48c14b6d1b
commit
02e5bc387f
14 files changed
+58
-15
No files matched your search
@@ -80,7 +80,7 @@ public:
|
||||
bool GetImageFromBuffer(std::vector<uint8_t> &v, int64_t image_number = -1);
|
||||
ImageBufferStatus GetImageBufferStatus() const;
|
||||
void ClearImageBuffer() const;
|
||||
void ClearResults() const; // previous run's status, plots and buffered images
|
||||
void ClearResults() const; // previous run's status, plots, live rugnux status and buffered images
|
||||
|
||||
void LoadDetectorPixelMask(PixelMask &mask);
|
||||
|
||||
|
||||
@@ -329,9 +329,9 @@ void JFJochStateMachine::Initialize() {
|
||||
ResetError(); // Clear error, we don't care what was it
|
||||
start_exception = nullptr; // Re-initialising discards a pending start failure
|
||||
|
||||
// A fresh start: no images from before, and no live rugnux analysis or model left over from the
|
||||
// previous user.
|
||||
services.ClearImageBuffer();
|
||||
// A fresh start: no images, plots or live rugnux status from before, and no live rugnux analysis
|
||||
// or model left over from the previous user.
|
||||
services.ClearResults();
|
||||
{
|
||||
std::unique_lock ul2(rugnux_mutex);
|
||||
RugnuxLiveSettings s = services.GetRugnuxLive();
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
/*
|
||||
* Rugnux_live_status.h
|
||||
*
|
||||
* Live rugnux processing of the last collection; kept until the next collection starts. Times are taken when the image puller received a message, and are in seconds since the first image (before it arrives, since now). The frame rate is `(images_received - 1) / last_image_s`.
|
||||
* Live rugnux processing of the last collection; kept until the next collection starts or `POST /initialize`. Times are taken when the image puller received a message, and are in seconds since the first image (before it arrives, since now). The frame rate is `(images_received - 1) / last_image_s`.
|
||||
*/
|
||||
|
||||
#ifndef Rugnux_live_status_H_
|
||||
@@ -29,7 +29,7 @@ namespace org::openapitools::server::model
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Live rugnux processing of the last collection; kept until the next collection starts. Times are taken when the image puller received a message, and are in seconds since the first image (before it arrives, since now). The frame rate is `(images_received - 1) / last_image_s`.
|
||||
/// Live rugnux processing of the last collection; kept until the next collection starts or `POST /initialize`. Times are taken when the image puller received a message, and are in seconds since the first image (before it arrives, since now). The frame rate is `(images_received - 1) / last_image_s`.
|
||||
/// </summary>
|
||||
class Rugnux_live_status
|
||||
{
|
||||
|
||||
@@ -2770,7 +2770,7 @@ components:
|
||||
rugnux_live_status:
|
||||
type: object
|
||||
description: |
|
||||
Live rugnux processing of the last collection; kept until the next collection starts.
|
||||
Live rugnux processing of the last collection; kept until the next collection starts or `POST /initialize`.
|
||||
Times are taken when the image puller received a message, and are in seconds since the first image
|
||||
(before it arrives, since now). The frame rate is `(images_received - 1) / last_image_s`.
|
||||
required:
|
||||
@@ -2917,7 +2917,7 @@ paths:
|
||||
This operation will reconfigure network interface of the detector.
|
||||
During operation of the detector it is recommended to use the `POST /pedestal` operation instead.
|
||||
If storage cells are used, the execution time might be few minutes.
|
||||
It also clears the image buffer, disables live rugnux analysis and removes the rugnux model.
|
||||
It also clears the image buffer, the previous collection's plots and live rugnux status, disables live rugnux analysis and removes the rugnux model.
|
||||
|
||||
This is async function - one needs to use `POST /wait_till_done` to ensure operation is done.
|
||||
responses:
|
||||
|
||||
@@ -16,7 +16,7 @@ import type { deleteConfigRugnuxModelData, deleteConfigRugnuxModelError, getConf
|
||||
* This operation will reconfigure network interface of the detector.
|
||||
* During operation of the detector it is recommended to use the `POST /pedestal` operation instead.
|
||||
* If storage cells are used, the execution time might be few minutes.
|
||||
* It also clears the image buffer, disables live rugnux analysis and removes the rugnux model.
|
||||
* It also clears the image buffer, the previous collection's plots and live rugnux status, disables live rugnux analysis and removes the rugnux model.
|
||||
*
|
||||
* This is async function - one needs to use `POST /wait_till_done` to ensure operation is done.
|
||||
*
|
||||
|
||||
@@ -28,7 +28,7 @@ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends
|
||||
* This operation will reconfigure network interface of the detector.
|
||||
* During operation of the detector it is recommended to use the `POST /pedestal` operation instead.
|
||||
* If storage cells are used, the execution time might be few minutes.
|
||||
* It also clears the image buffer, disables live rugnux analysis and removes the rugnux model.
|
||||
* It also clears the image buffer, the previous collection's plots and live rugnux status, disables live rugnux analysis and removes the rugnux model.
|
||||
*
|
||||
* This is async function - one needs to use `POST /wait_till_done` to ensure operation is done.
|
||||
*
|
||||
|
||||
@@ -1943,7 +1943,7 @@ export type rugnux_summary_row = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Live rugnux processing of the last collection; kept until the next collection starts.
|
||||
* Live rugnux processing of the last collection; kept until the next collection starts or `POST /initialize`.
|
||||
* Times are taken when the image puller received a message, and are in seconds since the first image
|
||||
* (before it arrives, since now). The frame rate is `(images_received - 1) / last_image_s`.
|
||||
*
|
||||
|
||||
@@ -824,7 +824,7 @@ export const zRugnuxSummaryRow = z.object({
|
||||
});
|
||||
|
||||
/**
|
||||
* Live rugnux processing of the last collection; kept until the next collection starts.
|
||||
* Live rugnux processing of the last collection; kept until the next collection starts or `POST /initialize`.
|
||||
* Times are taken when the image puller received a message, and are in seconds since the first image
|
||||
* (before it arrives, since now). The frame rate is `(images_received - 1) / last_image_s`.
|
||||
*
|
||||
|
||||
@@ -355,6 +355,7 @@ void JFJochReceiverService::ClearResults() {
|
||||
receiver_status.Clear();
|
||||
receiver_status.SetProgress({});
|
||||
plots.Clear();
|
||||
rugnux_status.Clear();
|
||||
image_buffer.Finalize(std::chrono::milliseconds(2500));
|
||||
}
|
||||
|
||||
|
||||
@@ -101,8 +101,8 @@ public:
|
||||
std::string GetJPEGFromBuffer(const PreviewImageSettings &settings, int64_t image_number = ImageBuffer::MaxImage);
|
||||
ImageBufferStatus GetImageBufferStatus() const;
|
||||
void ClearImageBuffer();
|
||||
// Drop everything the previous run left readable - its status, plots and buffered images - so
|
||||
// nothing of it is served under the next run's tokens. Idle only.
|
||||
// Drop everything the previous run left readable - its status, plots, live rugnux status and
|
||||
// buffered images - so nothing of it is served under the next run's tokens. Idle only.
|
||||
void ClearResults();
|
||||
|
||||
ImagePusherStatus GetImagePusherStatus() const;
|
||||
|
||||
@@ -106,6 +106,12 @@ void RugnuxLiveStatus::Warning(const std::string &text) {
|
||||
s.warnings.push_back(text);
|
||||
}
|
||||
|
||||
void RugnuxLiveStatus::Clear() {
|
||||
std::unique_lock ul(m);
|
||||
s = RugnuxLiveSnapshot{};
|
||||
last_image.reset();
|
||||
}
|
||||
|
||||
RugnuxLiveSnapshot RugnuxLiveStatus::Get() const {
|
||||
std::unique_lock ul(m);
|
||||
RugnuxLiveSnapshot ret = s;
|
||||
|
||||
@@ -81,5 +81,7 @@ public:
|
||||
void Cut(const std::string &reason);
|
||||
void Probe(const std::string &text);
|
||||
void Warning(const std::string &text);
|
||||
// Back to Idle with nothing of the last run, as before any collection.
|
||||
void Clear();
|
||||
RugnuxLiveSnapshot Get() const;
|
||||
};
|
||||
@@ -69,7 +69,8 @@ TEST_CASE("JFJochBrokerHttp_BearerTokens", "[broker]") {
|
||||
for (const char *path: {"/statistics/data_collection", "/result/scan", "/image_buffer/start.cbor",
|
||||
"/image_buffer/image.cbor?id=0", "/image_buffer/image.tiff?id=0",
|
||||
"/image_buffer/image.jpeg?id=0", "/preview/plot?type=bkg_estimate",
|
||||
"/preview/plot.bin?type=bkg_estimate", "/live/events"}) {
|
||||
"/preview/plot.bin?type=bkg_estimate", "/live/events",
|
||||
"/config/rugnux", "/rugnux/status"}) {
|
||||
INFO(path);
|
||||
auto res = client.Get(path);
|
||||
REQUIRE(res);
|
||||
@@ -78,6 +79,11 @@ TEST_CASE("JFJochBrokerHttp_BearerTokens", "[broker]") {
|
||||
REQUIRE(res->body.find("protected_run") == std::string::npos);
|
||||
REQUIRE(client.Get(path, wrong)->status == 401);
|
||||
}
|
||||
// Live rugnux settings and its model are the dataset's too: changed only with a token.
|
||||
REQUIRE(client.Put("/config/rugnux", R"({"enable":false})", "application/json")->status == 401);
|
||||
REQUIRE(client.Put("/config/rugnux/model", "", "application/octet-stream")->status == 401);
|
||||
REQUIRE(client.Delete("/config/rugnux/model")->status == 401);
|
||||
REQUIRE(client.Delete("/config/rugnux/model", wrong)->status == 401);
|
||||
}
|
||||
|
||||
SECTION("either token opens them") {
|
||||
@@ -86,6 +92,8 @@ TEST_CASE("JFJochBrokerHttp_BearerTokens", "[broker]") {
|
||||
REQUIRE(res->body.find("protected_run") != std::string::npos);
|
||||
REQUIRE(client.Get("/statistics/data_collection", other)->status == 200);
|
||||
REQUIRE(client.Get("/preview/plot?type=bkg_estimate", good)->status == 200);
|
||||
REQUIRE(client.Get("/rugnux/status", good)->status == 200);
|
||||
REQUIRE(client.Get("/config/rugnux", other)->status == 200);
|
||||
}
|
||||
|
||||
SECTION("the aggregate statistics drop the measurement block instead of refusing") {
|
||||
|
||||
@@ -46,6 +46,32 @@ TEST_CASE("RugnuxLiveStatus_BeforeFirstImage", "[RugnuxLive]") {
|
||||
CHECK(!status.LastImage());
|
||||
}
|
||||
|
||||
TEST_CASE("RugnuxLiveStatus_Clear", "[RugnuxLive]") {
|
||||
RugnuxLiveStatus status;
|
||||
status.Start(10, 1.0, std::chrono::steady_clock::now() - 2s);
|
||||
status.ImageReceived(std::chrono::steady_clock::now() - 1s);
|
||||
status.Step("indexing");
|
||||
status.Probe("lattice found");
|
||||
status.Result("OK", "fine", {{"Space group", "P 1"}}, {"a warning"});
|
||||
status.Finish(RugnuxLiveState::Done);
|
||||
REQUIRE(status.LastImage());
|
||||
|
||||
status.Clear();
|
||||
const auto s = status.Get();
|
||||
CHECK(s.state == RugnuxLiveState::Idle);
|
||||
CHECK(s.images_expected == 0);
|
||||
CHECK(s.images_received == 0);
|
||||
CHECK(s.steps.empty());
|
||||
CHECK(s.probe.empty());
|
||||
CHECK(s.verdict.empty());
|
||||
CHECK(s.summary.empty());
|
||||
CHECK(s.warnings.empty());
|
||||
CHECK(!s.start_to_first_image_s);
|
||||
CHECK(!s.last_image_s);
|
||||
CHECK(s.elapsed_s == 0.0);
|
||||
CHECK(!status.LastImage());
|
||||
}
|
||||
|
||||
TEST_CASE("TestImagePuller_SetsReceiveTime", "[RugnuxLive]") {
|
||||
TestImagePuller puller;
|
||||
const auto before = std::chrono::steady_clock::now();
|
||||
|
||||
Reference in new issue
Block a user