fix(runtime): harden batch forwarding — detach pins, malformed-raise guard, struct items
This commit is contained in:
@@ -109,8 +109,11 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
/// (#519) — not a severity bucket. Classify it with <see cref="OpcUaStatus.IsGood"/> and friends rather
|
||||
/// than comparing it to <see cref="OpcUaStatus.Good"/>.</para></summary>
|
||||
public sealed record AttributeValuePublished(string DriverInstanceId, string FullReference, object? Value, uint StatusCode, DateTime TimestampUtc);
|
||||
/// <summary>One value within an <see cref="AttributeValueBatchPublished"/>.</summary>
|
||||
public sealed record AttributeValueItem(string FullReference, object? Value, uint StatusCode, DateTime TimestampUtc);
|
||||
/// <summary>One value within an <see cref="AttributeValueBatchPublished"/>.
|
||||
/// <para>A struct deliberately: an <c>AttributeValueItem[]</c> then holds its items inline, so a burst of
|
||||
/// N values costs one array allocation instead of one array plus N boxes. Indexed access through
|
||||
/// <see cref="IReadOnlyList{T}"/> does not box.</para></summary>
|
||||
public readonly record struct AttributeValueItem(string FullReference, object? Value, uint StatusCode, DateTime TimestampUtc);
|
||||
/// <summary>Batched form of <see cref="AttributeValuePublished"/> — every changed attribute of ONE
|
||||
/// driver production burst in one message. The parent fans the whole batch to the mux and the OPC UA
|
||||
/// publish path in one hop each. Status codes ride verbatim (#519).</summary>
|
||||
@@ -900,7 +903,13 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
// Tell, one parent hop, one mux pass per burst instead of per tag.
|
||||
if (subscribable is IBatchSubscribable batchable)
|
||||
{
|
||||
_batchChangeHandler = (_, args) => self.Tell(new DataChangeBatchForward(args.Items));
|
||||
_batchChangeHandler = (_, args) =>
|
||||
{
|
||||
// A null/empty raise from a buggy driver must never enter the mailbox: an unguarded null
|
||||
// would throw in the handler, restart the actor, and tear down the driver transport.
|
||||
if (args?.Items is not { Count: > 0 }) return;
|
||||
self.Tell(new DataChangeBatchForward(args.Items));
|
||||
};
|
||||
batchable.OnDataChangeBatch += _batchChangeHandler;
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user