Co się dzieje z zapisami, gdy ChannelOutboundBuffer jest pełny

Nov 20 2020

Próbuję dowiedzieć się, co się dzieje z pisaniem żądań, gdy kanał nie odpowiada. Na przykład dzieje się tak, gdy peer nagle odłącza się od sieci i nigdy nie otrzymujemy RST.

Z czytania dokumentacji i Zrozumienia buforów kanałów i znaków wodnych Netty wynika, że po osiągnięciu wysokiego WriterBufferWaterMark , ChannelOutboundBuffer zostanie uznany za pełny i:

Channel.isWritable () zacznie zwracać wartość false.

Z Channel.isWritable () :

Zwraca wartość true wtedy i tylko wtedy, gdy wątek we / wy natychmiast wykona żądaną operację zapisu. Wszelkie żądania zapisu wykonane, gdy ta metoda zwróci wartość false, są umieszczane w kolejce do momentu, gdy wątek we / wy będzie gotowy do przetwarzania żądań zapisu w kolejce.

Moje początkowe pytanie brzmiało: Co się dzieje, kiedy nadal piszemy ?

Gdzie dane zostaną umieszczone w kolejce, jeśli kanał Netty isWritable zwraca false, stwierdza, że ​​istnieje bufor wewnętrzny i sugeruje, że jest on nieograniczony.

Powstaje pytanie, gdzie dokładnie znajdują się w kolejce żądania zapisu, a co ważniejsze, czy mogę obserwować rozmiar tych kolejek ?

Lub: czy istnieje jakiś limit, kiedy Netty / OS wykryje, że połączenie jest zerwane i musi zostać zamknięte?

Odpowiedzi

1 NormanMaurer Nov 24 2020 at 08:59

Nadal będzie w kolejce ChannelOutboundBuffer. Jesteś odpowiedzialny za zaprzestanie zapisywania, gdy bufor się zapełni i ponowne rozpoczęcie opróżniania. Możesz to zaobserwować poprzez ChannelInboundHandler.channelWritabilityChanged(...).

cfstras Nov 25 2020 at 12:30

Patrząc na źródło ChannelOutboundBuffer w 4.1.37, metoda addMessagezawsze dodaje wiadomości przychodzące do wewnętrznej połączonej listy, niezależnie od stanuisWritable . Ta lista jest nieograniczona.

Całkowita długość tego bufora w bajtach jest osiągalna poprzez channel.unsafe().outboundBuffer().totalPendingWriteBytes().

W przypadku wartości pośredniej, jeśli nie chcesz używać unsafe (), możesz alternatywnie użyć funkcji, channel.bytesBeforeWritable()która zwróci bajty w kolejce minus niski znak wodny.