perf(ablegacy): coalesce adjacent N/B/F/L scalar reads into one PCCC request
Review 07 P7 (rest): adjacent words on one data file were never coalesced (one round trip per tag) although the array path proves the transport can read a span. Within a device pass, scalar tags on one N/B/F/L file within 8 elements of each other (block <= 200 data bytes, under the 236-byte typed-read limit) now ride one multi-element read and are decoded from their offsets with exactly the CLR types the single-tag path returns (int / float / bool). Only shapes the single path decodes identically are coalesced: indirect, sub-element, array, file-number-less (S:/I:/O:) and width-mismatched tags keep the single path. A block the device refuses (an authored element past the end of the file, a native PLC-5 non-N file) falls back to per-tag reads for its members and its shape is remembered; a comms fault fails the members together. New driver-config key coalesceReads (default true) with an AdminUI switch (Razor change: AbLegacyDriverForm, for the Wave 4 live check). Adds an env-gated ab_server parity case (coalesced == per-tag values). Refs #738 Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
This commit is contained in:
+11
-1
@@ -28,6 +28,13 @@
|
||||
</InputSelect>
|
||||
<div class="form-text">Which protocol stack talks to the controller. Default omits the setting (libplctag). Native is opt-in: wire-proven only for N-file reads/writes and F8 reads. Takes effect on the next deploy.</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-check form-switch mt-4">
|
||||
<InputCheckbox @bind-Value="_form.CoalesceReads" @bind-Value:after="EmitAsync" class="form-check-input" id="ablegacyCoalesceReads" />
|
||||
<label class="form-check-label" for="ablegacyCoalesceReads">Coalesce adjacent reads</label>
|
||||
</div>
|
||||
<div class="form-text">Read nearby scalar tags on one N/B/F/L file as a single PCCC request. A block the PLC refuses falls back to per-tag reads automatically. Default on.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -97,7 +104,7 @@
|
||||
/// <summary>JSON paths this form edits; everything else in the stored config is preserved.</summary>
|
||||
internal static readonly string[] OwnedPaths =
|
||||
[
|
||||
"transport", "probeTimeoutSeconds",
|
||||
"transport", "probeTimeoutSeconds", "coalesceReads",
|
||||
"probe.enabled", "probe.probeAddress",
|
||||
];
|
||||
|
||||
@@ -163,6 +170,7 @@
|
||||
// PLC-5 / LogixPccc exclusion still applies). Never re-emit a concrete default here — that would pin
|
||||
// every edited driver to it.
|
||||
public AbLegacyTransport? Transport { get; set; }
|
||||
public bool CoalesceReads { get; set; } = true;
|
||||
|
||||
// Probe
|
||||
public bool ProbeEnabled { get; set; } = true;
|
||||
@@ -200,6 +208,7 @@
|
||||
_loadedProbeTimeout = o.Probe.Timeout,
|
||||
TimeoutSeconds = (int)o.Timeout.TotalSeconds,
|
||||
Transport = o.Transport,
|
||||
CoalesceReads = o.CoalesceReads,
|
||||
ProbeEnabled = o.Probe.Enabled,
|
||||
ProbeIntervalSeconds = (int)o.Probe.Interval.TotalSeconds,
|
||||
ProbeTimeoutSeconds = (int)o.Probe.Timeout.TotalSeconds,
|
||||
@@ -220,6 +229,7 @@
|
||||
},
|
||||
Timeout = DriverConfigMs.Save(TimeoutSeconds, _loadedTimeout),
|
||||
Transport = Transport,
|
||||
CoalesceReads = CoalesceReads,
|
||||
ProbeTimeoutSeconds = AdminProbeTimeoutSeconds,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user