fix(historian): #691.4 review — Null reports SupportsReverseEvents = true, like raw
The null source has no history in either direction; reporting false made the server walk an empty reverse events read back through three empty forward reads. It now answers the reverse overload with the empty result itself (guard test unchanged: it still declares both members).
This commit is contained in:
@@ -143,8 +143,8 @@ public interface IHistorianDataSource : IDisposable
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The default forwards a forward read to the five-argument overload and throws
|
||||
/// <see cref="NotSupportedException"/> for a reverse one — a backend that cannot read newest-first (Gateway,
|
||||
/// Null). The server never relies on that throw: it consults <see cref="SupportsReverseEvents"/> first and walks
|
||||
/// <see cref="NotSupportedException"/> for a reverse one — a backend that cannot read newest-first (the
|
||||
/// Gateway). The server never relies on that throw: it consults <see cref="SupportsReverseEvents"/> first and walks
|
||||
/// such a read back from forward reads (#691.4), never returning the earliest events in ascending order as if
|
||||
/// they were the answer. A backend that serves reverse natively must override BOTH members.
|
||||
/// </para>
|
||||
|
||||
@@ -61,13 +61,12 @@ public sealed class NullHistorianDataSource : IHistorianDataSource
|
||||
public bool SupportsReverseRaw => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <remarks><c>false</c> (Gitea #675): there is no history to read in either direction; the server walks a reverse
|
||||
/// read back from (empty) forward reads like any backend that cannot read newest-first (#691.4).</remarks>
|
||||
public bool SupportsReverseEvents => false;
|
||||
/// <remarks><c>true</c>, like <see cref="SupportsReverseRaw"/> (Gitea #691.4 review; <c>false</c> under #675): there is no
|
||||
/// history to read in either direction — no need for the server to walk back through empty forward reads.</remarks>
|
||||
public bool SupportsReverseEvents => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <remarks>Forward ⇒ the empty result; reverse ⇒ <see cref="NotSupportedException"/>, the interface contract for a
|
||||
/// backend without <see cref="SupportsReverseEvents"/>.</remarks>
|
||||
/// <remarks>The empty result in either direction.</remarks>
|
||||
public Task<HistoricalEventsResult> ReadEventsAsync(
|
||||
string? sourceName,
|
||||
DateTime startUtc,
|
||||
@@ -75,9 +74,7 @@ public sealed class NullHistorianDataSource : IHistorianDataSource
|
||||
int maxEvents,
|
||||
bool reverse,
|
||||
CancellationToken cancellationToken) =>
|
||||
reverse
|
||||
? throw new NotSupportedException("The null historian cannot read events newest-first (reverse).")
|
||||
: Task.FromResult(EmptyEvents);
|
||||
Task.FromResult(EmptyEvents);
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <remarks>
|
||||
|
||||
@@ -5291,7 +5291,7 @@ public sealed class OtOpcUaNodeManager : CustomNodeManager2
|
||||
reverse = startUtc > endUtc;
|
||||
}
|
||||
|
||||
// A reverse read on a backend that cannot read newest-first (Gateway, Null) is never sent there (#675 refused it
|
||||
// A reverse read on a backend that cannot read newest-first (the Gateway) is never sent there (#675 refused it
|
||||
// here); since #691.4 it is walked back from bounded forward reads — the raw walk (#686), with ties ordered by
|
||||
// EventId because the gateway orders by event time only. Decided by the capability, not by catching an
|
||||
// exception, so a NotSupportedException thrown from inside a backend stays a backend fault.
|
||||
|
||||
@@ -9,7 +9,7 @@ internal readonly record struct ReverseEventsPage(List<HistoricalEvent> Events,
|
||||
|
||||
/// <summary>
|
||||
/// Gitea #691.4: serves a Part 11 reverse events read — <c>(lo, hi]</c> newest-first — on a backend that reads events
|
||||
/// forward only (<see cref="IHistorianDataSource.SupportsReverseEvents"/> = <c>false</c>: Gateway, Null) with the
|
||||
/// forward only (<see cref="IHistorianDataSource.SupportsReverseEvents"/> = <c>false</c>: the Gateway) with the
|
||||
/// <see cref="ReverseWalk"/>. A segment read is cut short when the source flags truncation (its continuation point); ties
|
||||
/// are ordered by <see cref="EventIdTieOrder"/> because the gateway orders by event time only.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user