perf: optimize MQTT cross-protocol path (0.30x → 0.78x Go)

Replace per-message async fire-and-forget with direct-buffer write loop
mirroring NatsClient pattern: SpinLock-guarded buffer append, double-
buffer swap, single WriteAsync per batch.

- MqttConnection: add _directBuf/_writeBuf + RunMqttWriteLoopAsync
- MqttConnection: add EnqueuePublishNoFlush (zero-alloc PUBLISH format)
- MqttPacketWriter: add WritePublishTo(Span<byte>) + MeasurePublish
- MqttTopicMapper: add NatsToMqttBytes with bounded ConcurrentDictionary
- MqttNatsClientAdapter: synchronous SendMessageNoFlush + SignalFlush
- Skip FlushAsync on plain TCP sockets (TCP auto-flushes)
This commit is contained in:
Joseph Doherty
2026-03-13 14:25:13 -04:00
parent 699449da6a
commit 11e01b9026
14 changed files with 1113 additions and 10 deletions

View File

@@ -5,3 +5,12 @@ public class BenchmarkCoreCollection : ICollectionFixture<CoreServerPairFixture>
[CollectionDefinition("Benchmark-JetStream")]
public class BenchmarkJetStreamCollection : ICollectionFixture<JetStreamServerPairFixture>;
[CollectionDefinition("Benchmark-Mqtt")]
public class BenchmarkMqttCollection : ICollectionFixture<MqttServerFixture>;
[CollectionDefinition("Benchmark-Tls")]
public class BenchmarkTlsCollection : ICollectionFixture<TlsServerFixture>;
[CollectionDefinition("Benchmark-WebSocket")]
public class BenchmarkWebSocketCollection : ICollectionFixture<WebSocketServerFixture>;