fix: the warn-once latches reset on a CONFIG, so a reconnect is diagnosed too
Four latches were process-lifetime -- two of them function-local statics, so process-wide rather than per-object -- and a condition that warned once stayed silent about every later occurrence in a long-lived session. A diagnostic that goes quiet after the first occurrence is the failure mode worth fixing in a feature whose job is diagnosis. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
8320988d96
commit
51d13a09cb
2 files changed
+16
-6
No files matched your search
+11
-6
@@ -122,6 +122,13 @@ void Acquisition::on_config(const udps_signal_t* signals, std::uint32_t count,
|
|||||||
sig.time_signal_idx, sig.unit.c_str());
|
sig.time_signal_idx, sig.unit.c_str());
|
||||||
}
|
}
|
||||||
std::fflush(stderr);
|
std::fflush(stderr);
|
||||||
|
// The warn-once latches are per *connection*, not per process. A reconnect re-enters here, and
|
||||||
|
// a diagnostic that goes quiet after the first occurrence of a condition that recurs on the
|
||||||
|
// next session is the failure mode worth avoiding in a feature whose whole job is diagnosis.
|
||||||
|
warned_batch_ = false;
|
||||||
|
warned_outage_ = false;
|
||||||
|
warned_bridge_ = false;
|
||||||
|
warned_time_source_ = false;
|
||||||
model_.stats().have_config.store(true, std::memory_order_relaxed);
|
model_.stats().have_config.store(true, std::memory_order_relaxed);
|
||||||
model_.set_signals(std::move(info));
|
model_.set_signals(std::move(info));
|
||||||
}
|
}
|
||||||
@@ -349,9 +356,8 @@ std::uint32_t Acquisition::build_stamps(const udps_frame_t* frame, int time_sign
|
|||||||
const double from = last_stream_anchor_;
|
const double from = last_stream_anchor_;
|
||||||
for (std::uint32_t k = 0; k < n; ++k) stamps_[k] = from + double(k + 1) * step;
|
for (std::uint32_t k = 0; k < n; ++k) stamps_[k] = from + double(k + 1) * step;
|
||||||
last_stream_anchor_ = stamps_[n - 1];
|
last_stream_anchor_ = stamps_[n - 1];
|
||||||
static bool bridged = false;
|
if (!warned_bridge_) {
|
||||||
if (!bridged) {
|
warned_bridge_ = true;
|
||||||
bridged = true;
|
|
||||||
std::fprintf(stderr,
|
std::fprintf(stderr,
|
||||||
"[udpscope] warning: the stream's time signal %s (%g..%g against a "
|
"[udpscope] warning: the stream's time signal %s (%g..%g against a "
|
||||||
"previous %g); bridging that packet at the declared cadence and "
|
"previous %g); bridging that packet at the declared cadence and "
|
||||||
@@ -360,9 +366,8 @@ std::uint32_t Acquisition::build_stamps(const udps_frame_t* frame, int time_sign
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
used_stream_time = false; // not a time base; fall back to arrival
|
used_stream_time = false; // not a time base; fall back to arrival
|
||||||
static bool warned = false;
|
if (!warned_time_source_) {
|
||||||
if (!warned) {
|
warned_time_source_ = true;
|
||||||
warned = true;
|
|
||||||
std::fprintf(stderr,
|
std::fprintf(stderr,
|
||||||
"[udpscope] warning: the stream's time signal %s (%g..%g); timing "
|
"[udpscope] warning: the stream's time signal %s (%g..%g); timing "
|
||||||
"samples by arrival instead. Check the time signal's mode and index "
|
"samples by arrival instead. Check the time signal's mode and index "
|
||||||
|
|||||||
@@ -127,6 +127,11 @@ class Acquisition {
|
|||||||
/// Warn-once latch for a loss past the reservation cap. A member, not a function-local
|
/// Warn-once latch for a loss past the reservation cap. A member, not a function-local
|
||||||
/// `static`, matching the latch Task 2 added for the same reason.
|
/// `static`, matching the latch Task 2 added for the same reason.
|
||||||
bool warned_outage_ = false;
|
bool warned_outage_ = false;
|
||||||
|
/// Warn-once latch for the one bridged packet whose time signal glitched.
|
||||||
|
bool warned_bridge_ = false;
|
||||||
|
/// Warn-once latch for the declared time signal failing for good, so the arrival clock is
|
||||||
|
/// taken instead.
|
||||||
|
bool warned_time_source_ = false;
|
||||||
/// The re-plan generation this object last reacted to. The buffer is re-planned whenever the
|
/// The re-plan generation this object last reacted to. The buffer is re-planned whenever the
|
||||||
/// model rebuilds it, and the state tied to the old store (`tick_` and the accumulators) is
|
/// model rebuilds it, and the state tied to the old store (`tick_` and the accumulators) is
|
||||||
/// reset when this falls behind `ScopeModel::plan_generation()`.
|
/// reset when this falls behind `ScopeModel::plan_generation()`.
|
||||||
|
|||||||
Reference in new issue
Block a user