fix(worker): review 2026-10-21 stream E — cache eviction, phased ReadBulk, poll/STA fault handling
- RemoveItem/Unregister evict value + write-completion caches (leak under churn) - ReadBulk snapshot path: add/advise all, one shared deadline, then tear down - alarm poll faults only after 3 consecutive failures; transient ones logged - AlarmCommandHandler disposes primary when standby build throws - StaRuntime pumps between queued work items - WRK-02: post-start STA loop death surfaces as StaHung WorkerFault - WRK-09: AppDomain unhandled-exception hook, exit code 7 - RETRIGGER documented as reserved, never synthesized - TST-05: live facts for Ping/GetSessionState/GetWorkerInfo/DrainEvents/ShutdownWorker
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using ZB.MOM.WW.MxGateway.Worker.Sta;
|
||||
|
||||
namespace ZB.MOM.WW.MxGateway.Worker.Tests.TestSupport;
|
||||
|
||||
/// <summary>
|
||||
/// Test <see cref="IStaMessagePump"/> that counts pump calls and can be armed
|
||||
/// to throw from the next pump, so tests can observe the STA loop's pump
|
||||
/// interleaving and drive a post-start loop death without a real Win32
|
||||
/// message queue. The idle wait blocks on the command wake event exactly
|
||||
/// like the production pump's <c>MsgWaitForMultipleObjectsEx</c> does.
|
||||
/// </summary>
|
||||
internal sealed class ControllableMessagePump : IStaMessagePump
|
||||
{
|
||||
private int pumpCount;
|
||||
private Exception? throwOnNextPump;
|
||||
|
||||
/// <summary>Gets the number of <see cref="PumpPendingMessages"/> calls so far.</summary>
|
||||
public int PumpCount => Volatile.Read(ref pumpCount);
|
||||
|
||||
/// <summary>Arms the pump to throw <paramref name="exception"/> from its next pump call.</summary>
|
||||
/// <param name="exception">The exception to throw once.</param>
|
||||
public void ThrowOnNextPump(Exception exception)
|
||||
{
|
||||
Volatile.Write(ref throwOnNextPump, exception);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void WaitForWorkOrMessages(WaitHandle commandWakeEvent, TimeSpan timeout)
|
||||
{
|
||||
commandWakeEvent.WaitOne(timeout);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int PumpPendingMessages()
|
||||
{
|
||||
Interlocked.Increment(ref pumpCount);
|
||||
Exception? exception = Interlocked.Exchange(ref throwOnNextPump, null);
|
||||
if (exception is not null)
|
||||
{
|
||||
throw exception;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user