fix(daemon): honour declared SECS-II formats + make service thread-safe
Audit fixes for two real bugs in the gRPC service: 1. Format compliance: to_item() wrote F8/I8 regardless of the variable's declared wire format, so values contradicted the S1F11/S1F21 namelists (ChamberPressure is F4, WaferCounter U4; the interop trace showed <F8 2.5> on the wire). Conversion now targets the declared format — verified end-to-end: secsgem-py now receives <F4 2.5> in S6F11. 2. Thread safety: gRPC handler threads called resolve_variable/resolve_event, copying live store entries (including Item values) while the io thread mutates them. The service now snapshots the immutable name->id/format maps at construction (before run_async, per the documented ordering); all writes already post to the io thread. Remaining known narrow race (GetControlState enum read) documented in DAEMON_ROADMAP. Also: drop a stale tools/run_interop.sh reference from docker-compose.yml. Tests: daemon in-process 16/16 (new F4/U4 format assertions), core 459/459, secsgem-py interop green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -46,16 +46,21 @@ TEST_CASE("Equipment gRPC service over an in-process channel") {
|
||||
CHECK(resp.state() == pb::ControlState::HOST_OFFLINE);
|
||||
}
|
||||
|
||||
SUBCASE("SetVariables accepts a known name and updates the model") {
|
||||
SUBCASE("SetVariables converts to the variable's declared wire format") {
|
||||
// ChamberPressure is declared F4 and WaferCounter U4 in equipment.yaml;
|
||||
// the daemon must honour those, not write F8/I8, or the host sees values
|
||||
// whose format contradicts the S1F11/S1F21 namelists.
|
||||
grpc::ClientContext ctx;
|
||||
pb::VariableUpdate req;
|
||||
pb::Ack resp;
|
||||
(*req.mutable_values())["ChamberPressure"].set_real(2.5);
|
||||
(*req.mutable_values())["WaferCounter"].set_integer(7);
|
||||
auto st = stub->SetVariables(&ctx, req, &resp);
|
||||
CHECK(st.ok());
|
||||
CHECK(resp.code() == pb::Ack::ACCEPT);
|
||||
rt.poll(); // drain the posted set_variable onto this thread
|
||||
CHECK(rt.model().dvids.value(101) == s2::Item::f8(2.5));
|
||||
CHECK(rt.model().dvids.value(101) == s2::Item::f4(2.5f));
|
||||
CHECK(rt.model().dvids.value(100) == s2::Item::u4(uint32_t{7}));
|
||||
}
|
||||
|
||||
SUBCASE("SetVariables rejects an unknown variable name") {
|
||||
|
||||
Reference in New Issue
Block a user