Git development
 help / color / mirror / Atom feed
From: "Robin Jarry" <robin.jarry@6wind.com>
To: "Junio C Hamano" <gitster@pobox.com>
Cc: "Emily Shaffer" <emilyshaffer@google.com>, <git@vger.kernel.org>,
	"Nicolas Dichtel" <nicolas.dichtel@6wind.com>,
	"Patryk Obara" <patryk.obara@gmail.com>,
	"Jiang Xin" <zhiyou.jx@alibaba-inc.com>
Subject: Re: [PATCH v2] receive-pack: add option to interrupt pre-receive when client exits
Date: Thu, 27 Jan 2022 10:32:12 +0100	[thread overview]
Message-ID: <CHGCP9P33XDQ.3FEWHU0PBMNU6@diabtop> (raw)
In-Reply-To: <xmqqv8y54wxc.fsf@gitster.g>

Junio C Hamano, Jan 27, 2022 at 05:36:
> I somehow feel that it is unrealistic to expect the command to be
> killed via SIGPIPE because there is no guarantee that the command
> has that many bytes to send out to to get the signal in the first
> place.  Such an expectation is simply wrong, isn't it?

Maybe I did not word that properly. Indeed, this only applies if
pre-receive has bytes to send out in the first place. This is what
I referred to with the last paragraph:

> > This does not guarantee that all client disconnections will abort
> > a push. If there is no pre-receive hook or if it does not produce
> > any output, receive-pack will not be killed via SIGPIPE and the push
> > will complete.

It would be much better not to rely on pre-receive to have bytes to send
and to expect that receive-pack will receive SIGPIPE when forwarding
them after the client has disconnected.

I thought of sending a "keepalive packet" in the socket *after* the
pre-receive hook has completed. I do not know the protocol details.
Would something like this be suitable:

diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 8718a6dd91b4..2e0ddd1a59fe 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -1990,16 +1990,28 @@ static void execute_commands(struct command *commands,
 	if (run_receive_hook(commands, "pre-receive", 0, push_options)) {
 		for (cmd = commands; cmd; cmd = cmd->next) {
 			if (!cmd->error_string)
 				cmd->error_string = "pre-receive hook declined";
 		}
 		return;
 	}
 
+	/*
+	 * Send a keepalive packet to ensure that the client has not
+	 * disconnected while pre-receive was running.
+	 */
+	{
+		static const char buf[] = "0001";
+		if (use_sideband)
+			send_sideband(1, 1, buf, sizeof(buf) - 1, use_sideband);
+		else
+			write_or_die(1, buf, sizeof(buf) - 1);
+	}
+
 	/*
 	 * Now we'll start writing out refs, which means the objects need
 	 * to be in their final positions so that other processes can see them.
 	 */
 	if (tmp_objdir_migrate(tmp_objdir) < 0) {
 		for (cmd = commands; cmd; cmd = cmd->next) {
 			if (!cmd->error_string)
 				cmd->error_string = "unable to migrate objects to permanent storage";

In that situation, if the client has exited, receive-pack should be
killed via SIGPIPE before completing the push.

> Is it safe to kill(2) from within a signal handler?

Even if it is, it is probably not a good idea. I did that to avoid
leaving a zombie after receive-pack has died. Maybe setting a flag in
the signal handler and checking the flag after the process has exited
would have been better.

> Why does this patch do anything more than a partial reversion of
> ec7dbd14 (receive-pack: allow hooks to ignore its standard input
> stream, 2014-09-12), i.e. "if the configuration says do not be
> lenient to hooks that do not consume their input, do not ignore
> sigpipe at all".

Indeed it is a partial reversion of that commit. Maybe the "keepalive
before migrating to permanent storage" solution is better.

What do you think?

  reply	other threads:[~2022-01-27  9:32 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-25  9:54 [PATCH] receive-pack: interrupt pre-receive when client disconnects Robin Jarry
2022-01-26  7:17 ` Jiang Xin
2022-01-26 12:46   ` Robin Jarry
2022-01-26 21:44 ` [PATCH v2] receive-pack: add option to interrupt pre-receive when client exits Robin Jarry
2022-01-27  3:21   ` Jiang Xin
2022-01-27  8:38     ` Robin Jarry
2022-01-27  4:36   ` Junio C Hamano
2022-01-27  9:32     ` Robin Jarry [this message]
2022-01-27 18:26       ` Junio C Hamano
2022-01-27 20:53         ` Robin Jarry
2022-01-27 21:55           ` [PATCH v3] receive-pack: check if client is alive before completing the push Robin Jarry
2022-01-28  1:19             ` Junio C Hamano
2022-01-28  9:13               ` Robin Jarry
2022-01-28 17:52             ` Junio C Hamano
2022-01-28 19:32               ` Robin Jarry
2022-01-28 19:48             ` [PATCH v4] " Robin Jarry
2022-02-04 11:37               ` Ævar Arnfjörð Bjarmason
2022-02-04 19:19                 ` Junio C Hamano
2022-02-07 19:26                 ` Robin Jarry
2022-01-27 23:47           ` [PATCH v2] receive-pack: add option to interrupt pre-receive when client exits Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CHGCP9P33XDQ.3FEWHU0PBMNU6@diabtop \
    --to=robin.jarry@6wind.com \
    --cc=emilyshaffer@google.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=nicolas.dichtel@6wind.com \
    --cc=patryk.obara@gmail.com \
    --cc=zhiyou.jx@alibaba-inc.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox