grpc / grpc/grpc-java

Simplify Netty pipeline using Buffering handler

Abierto
#789 7 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
Java
Estrellas
12.1k
Forks
4k
Merge medio
2 d 17 h
PR fusionados (30 d)
37

Descripción

The current pipeline configurations using one of the buffering handlers (tls, plaintext, etc.) are rather complicated and it's not always clear which handlers will handle exceptions in various cases.

We currently add the buffering handler and the HTTP/2 handler at startup. The buffering handler holds any writes until the startup handshake (e.g. SSL/TLS) completes, at which point it directs all buffered writes to the HTTP/2 handler. While those writes are occuring, the buffering handler stays in the pipeline (this is due to threading behavior of Netty WRT writes occuring outside of the event loop). If any problems occur while those writes are taking place, exception handling could occur in either the buffering handler or the HTTP/2 handler. It would be desirable to guarantee that exception handling can occur in only a single place at any point in time.

Proposed change:

Part 1): Add a ChannelHandlerAdapter as the last handler in the pipeline. Netty has a race condition when writes occur from outside of the event loop. The last ChannelHandlerContext is extracted in this thread and then the write is called. If however, the pipeline is changed between when the context is obtained and the write occurs ... badness ensues. As a workaround, there is some hacky code in the buffering handler to account for this race. A better solution to this problem would be to simply enforce the existence of a handler at the tail of the pipeline which never changes. This will just be a pass-through, but must implement the `write` method (this is to avoid another Netty gotcha, where it will skip handlers if it has determined that they are uninterested in the event).

Part 2): With the handler from Part 1 in place, the installation of the buffering and HTTP/2 handlers can be modified to a `replace`. Initially, only the buffering handler is installed (not the HTTP/2 handler). When the startup handshake completes successfully, the buffering handler will replace itself with the HTTP/2 handler, and then empty it's queued writes to the HTTP/2 handler.

In this way we guarantee that only one of these handlers exists in the pipeline at a time. Failures due to the initial handshake will be handled by the buffering handler. Failures due to writes will always be handled by the HTTP/2 handler.

@ejona86 FYI

Guía de contribución

Abrir la guía de contribución

Línea de trabajo

Comienza rastreando las configuraciones de pipeline que instalan los handlers de buffering y HTTP/2, y luego lee las rutas de startup-handshake y queued-write del handler de buffering. Verifica cómo Netty gestiona las escrituras fuera del event loop y cómo se propagan las excepciones. Se considera terminado cuando el pipeline tiene un tail handler estable, solo hay un handler de buffering o HTTP/2 presente a la vez y las rutas de fallo descritas no dejan lugar a ambigüedades.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
java
Área
backend, networking
Tipo de issue
Refactorización
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.