Files
mxaccessgw/src/ZB.MOM.WW.MxGateway.Worker.Tests/TestSupport/ControllableMessagePump.cs
T
Joseph Doherty 7618cafb6c
ci / nightly-windev (push) Has been skipped
ci / windows-x86 (push) Failing after 1m3s
ci / java (push) Successful in 2m17s
ci / portable (push) Failing after 4m42s
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
2026-10-22 06:19:32 -04:00

48 lines
1.5 KiB
C#

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;
}
}