diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess/WorkerPipeSecurity.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess/WorkerPipeSecurity.cs index 5c491e7ab..07cc6c394 100644 --- a/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess/WorkerPipeSecurity.cs +++ b/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess/WorkerPipeSecurity.cs @@ -50,11 +50,20 @@ internal static class WorkerPipeSecurity return security; } + /// + /// The pipe's buffer quota in each direction (lmxopcua#789). With a quota of 0 an overlapped write stays pending + /// until the peer has READ the bytes, so a blocking writer () + /// would wait out a full peer wake-up per frame — measured on windev as half the closed-loop throughput. With a + /// quota a write completes as soon as the bytes are buffered; a peer that stops reading still fills it and blocks + /// the writer, which the heartbeat monitor ends. + /// + internal const int BufferBytes = 1024 * 1024; + /// Creates the single-instance server end of a worker pipe with . /// The random pipe name. /// The ACL (). /// The server stream. public static NamedPipeServerStream CreateServer(string pipeName, PipeSecurity security) => NamedPipeServerStreamAcl.Create(pipeName, PipeDirection.InOut, maxNumberOfServerInstances: 1, - PipeTransmissionMode.Byte, PipeOptions.Asynchronous, inBufferSize: 0, outBufferSize: 0, security); + PipeTransmissionMode.Byte, PipeOptions.Asynchronous, inBufferSize: BufferBytes, outBufferSize: BufferBytes, security); }