Was passiert mit Schreibvorgängen, wenn ChannelOutboundBuffer voll ist?
Ich versuche herauszufinden, was beim Schreiben von Anforderungen passiert, wenn ein Kanal nicht reagiert. Dies geschieht beispielsweise, wenn der Peer plötzlich das Netzwerk verlässt und wir nie eine RST erhalten.
Aus dem Lesen von Dokumenten und dem Verstehen von Netty-Channel-Puffern und Wasserzeichen geht hervor , dass ChannelOutboundBuffer nach Erreichen des hohen WriterBufferWaterMark als voll betrachtet wird und:
Channel.isWritable () gibt false zurück.
Von Channel.isWritable () :
Gibt nur dann true zurück, wenn der E / A-Thread den angeforderten Schreibvorgang sofort ausführt. Alle Schreibanforderungen, die gestellt werden, wenn diese Methode false zurückgibt, werden in die Warteschlange gestellt, bis der E / A-Thread bereit ist, die in der Warteschlange befindlichen Schreibanforderungen zu verarbeiten.
Meine erste Frage war: Was passiert, wenn wir trotzdem weiter schreiben ?
Wo werden die Daten in die Warteschlange gestellt, wenn Netty Channel isWritable den Wert false zurückgibt , dass ein interner Puffer vorhanden ist, und impliziert, dass er unbegrenzt ist?
Es stellt sich die Frage, wo genau sich die Schreibanforderungen in der Warteschlange befinden. Und was noch wichtiger ist, kann ich die Größe dieser Warteschlangen beobachten ?
Oder: Gibt es eine Grenze, an der Netty / OS erkennt, dass die Verbindung unterbrochen ist und geschlossen werden muss?
Antworten
Es wird weiterhin in die Warteschlange gestellt ChannelOutboundBuffer
. Sie sind dafür verantwortlich, das Schreiben zu beenden, sobald der Puffer voll ist, und erneut zu starten, sobald er geleert ist. Sie können dies über beobachten ChannelInboundHandler.channelWritabilityChanged(...)
.
Wenn Sie sich die Quelle für ChannelOutboundBuffer in 4.1.37 ansehen, addMessage
fügt die Methode eingehende Nachrichten immer zu einer internen verknüpften Liste hinzu, unabhängig vom Status vonisWritable
. Diese Liste wächst unbegrenzt.
Die Gesamtbytelänge dieses Puffers ist über erreichbar channel.unsafe().outboundBuffer().totalPendingWriteBytes()
.
Wenn Sie für einen indirekten Wert nicht unsafe () verwenden möchten, können Sie alternativ auch verwenden, channel.bytesBeforeWritable()
wodurch die Bytes in der Warteschlange abzüglich des niedrigen Wasserzeichens zurückgegeben werden.