Create PackObjectsHookStream (client and server in Gitaly)
Add a new RPC PackObjectsHookStream
to HookService.
Semantics
In the request message, the client (gitaly-hooks
) sends the Repository
object and the list of pack-objects arguments. The server can accept or reject the request based on this. If the server accepts, the client copies stdin
to the server via the stream socket. This is the same as what we do in PackObjectsHook.
The server response will be slightly different. PackObjectsHook returns two streams, multiplexed via Protobuf message fields, and a final gRPC status code. In PackObjectsStream we don't want to use Protobuf and there is no final status code in StreamRPC.
Instead, the PackObjectsHookStream response should use the Git pktline side-band-64k scheme. Side band 1
carries stdout, and side band 2
carries stderr. If git pack-objects
finishes successfully (exit status 0), the PackObjectsStream server send a final "flush" packet 0000
. If the client (gitaly-hooks
) sees the flush packet it hangs up and exits with status 0. If the client encounters an error while receiving the response, or if the response does not end in the flush packet, the client exits with status 1
to signal to git upload-pack
(its parent) that there was a problem.
The reason for this specific scheme is the fact that PackObjectsHook already uses side-band-64k internally. The only thing that has to change is adding the final flush packet so that a client can tell from the response stream alone what the exit status was.
Outcome
When this is done we have a Gitaly feature flag that controls whether gitaly-hooks
calls the old PackObjectsHook RPC or the new PackObjectsHookStream RPC. We can then roll out and observe PackObjectsHookStream handling real traffic in #1187 (closed)