Add half-close capability to Gitaly sidechannel
For gitlab-com/gl-infra/scalability#1278 (closed)
This MR is to add the half-close capability to Gitaly sidechannel. Half-close ability is important to signal the server that the client finishes data transformation. A typical flow looks like following:
- The client writes data into the connecton.
- The client half-closes the connection. The server is aware of this event when reading operations return EOF.
- The server writes the data back to the client, then close the connection.
- The client read the data until EOF
This flow is typical in existing RPS like PostUploadPack. Without half-closed ability, the server has no idea when the client stops sending data.
As sidechannel is built on top of Yamux stream, half-close ability is not supported. Therefore, we apply a length-prefix framing protocol, simiarly to Git pktline protocol, except we omit the band number. The half-close event is signaled by sending a flush packet.
This is an example of the data written into the wire:
| 4-byte length, including size of length itself.
v
0009Hello0000
^
| Flush packet signaling a half-close event
Many methods in battle-tested pktline package are re-used to save us some times. The data is frame when writing data from the client only; server writes are not affected. At the moment, we don't need server-client half-closed ability. And it may affect the performance when wrapping huge data sent from the server. In the future, if we have this use case, we can unify ServerConn and ClientConn into one Conn struct.
The framing protocol should be transparent from both clients and servers. The translation is done automatically by ServerConn and ClientConn.