git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Robin Jarry <robin.jarry@6wind.com>
Cc: git@vger.kernel.org, Emily Shaffer <emilyshaffer@google.com>,
	Nicolas Dichtel <nicolas.dichtel@6wind.com>,
	Patryk Obara <patryk.obara@gmail.com>,
	Jiang Xin <zhiyou.jx@alibaba-inc.com>
Subject: Re: [PATCH v3] receive-pack: check if client is alive before completing the push
Date: Fri, 28 Jan 2022 09:52:12 -0800	[thread overview]
Message-ID: <xmqq4k5nychf.fsf@gitster.g> (raw)
In-Reply-To: <20220127215553.1386024-1-robin.jarry@6wind.com> (Robin Jarry's message of "Thu, 27 Jan 2022 22:55:53 +0100")

Robin Jarry <robin.jarry@6wind.com> writes:

> Abort the push operation (i.e. do not migrate the objects from temporary
> to permanent storage) if the client has disconnected while the
> pre-receive hook was running.
>
> This reduces the risk of inconsistencies on network errors or if the
> user hits ctrl-c while the pre-receive hook is running.
>
> Send a keepalive packet (empty) on sideband 2 (the one to report
> progress). If the client has exited, receive-pack will be killed via
> SIGPIPE and the push will be aborted. This only works when sideband*
> capabilities are advertised by the client.

If they have already exited but the fact hasn't reached us over the
network, the write() will succeed to deposit the packet in the send
buffer.  So I am not sure how much this would actually help, but it
should be safe to send an unsolicited keepalive as long as the other
side is expecting to hear from us.  When either report_status or
report_status_v2 capabilities is in effect, we will make a report()
or report_v2() call later, so we should be safe.

> Signed-off-by: Robin Jarry <robin.jarry@6wind.com>
> ---
> v2 -> v3:
>     I had missed Documentation/technical/pack-protocol.txt. Using
>     sideband 2 to send the keepalive packet works.
>
>  builtin/receive-pack.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
> index 9f4a0b816cf9..8b0d56897c9f 100644
> --- a/builtin/receive-pack.c
> +++ b/builtin/receive-pack.c
> @@ -1971,6 +1971,15 @@ static void execute_commands(struct command *commands,
>  		return;
>  	}
>  
> +	/*
> +	 * Send a keepalive packet on sideband 2 (progress info) to ensure that
> +	 * the client has not disconnected while pre-receive was running.
> +	 */

I suspect that any keepalive, unless it expects an active "yes, I am
still alive" response from the other side, is too weak to "ensure".

I guess "to notice a client that has disconnected (e.g. killed with
^C)" is more appropriate.

> +	if (use_sideband) {
> +		static const char buf[] = "0005\2";
> +		write_or_die(1, buf, sizeof(buf) - 1);
> +	}

Observing how execute_commands() and helper functions report an
error to the callers higher in the call chain, and ask them to abort
the remainder of the operation, I am not sure if write_or_die() is
appropriate.

    Side note: inside copy_to_sideband(), which runs in async, it is
    a different matter (i.e. the main process on our side is not
    what gets killed by that _or_die() part of the call), but this
    one kills the main process.

The convention around this code path seems to be to fill explanation
of error in cmd->error_string and return to the caller.  In this
case, the error_strings may not reach the pusher via report() or
report_v2() as they may have disconnected, but calling the report()
functions is not the only thing the caller will want to do after
calling us, so giving it a chance to clean up may be a better
design, e.g.

	if (write_in_full(...) < 0) {
		for (cmd = commands; cmd; cmd = cmd->next)
	        	cmd->error_string = "pusher went away";
		return;
	}

Yes, the current code will not actually use the error string in any
useful way in this particular case, since report() or report_v2()
will have nobody listening to them.  But being consistent will help
maintaining the caller, as it can later be extended to use it
locally (e.g. log the request and its outcome, check which cmd has
succeeded and failed using the NULL-ness of cmd->error_string, etc.)

  parent reply	other threads:[~2022-01-28 17:52 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
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 [this message]
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

  List information: http://vger.kernel.org/majordomo-info.html

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

  git send-email \
    --in-reply-to=xmqq4k5nychf.fsf@gitster.g \
    --to=gitster@pobox.com \
    --cc=emilyshaffer@google.com \
    --cc=git@vger.kernel.org \
    --cc=nicolas.dichtel@6wind.com \
    --cc=patryk.obara@gmail.com \
    --cc=robin.jarry@6wind.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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).