From: Eric Sunshine <sunshine@sunshineco.com>
To: Stefan Beller <sbeller@google.com>
Cc: ronnie sahlberg <ronniesahlberg@gmail.com>,
Michael Haggerty <mhagger@alum.mit.edu>,
Jonathan Nieder <jrnieder@gmail.com>,
Git List <git@vger.kernel.org>,
Ronnie Sahlberg <sahlberg@google.com>
Subject: Re: [PATCHv4 4/6] receive-pack.c: use a single ref_transaction for atomic pushes
Date: Thu, 18 Dec 2014 17:26:55 -0500 [thread overview]
Message-ID: <CAPig+cS9hJBga7BU-YC3bNG23Tb30kQsXydwGyRYb1T_0fiVqw@mail.gmail.com> (raw)
In-Reply-To: <1418924706-9843-1-git-send-email-sbeller@google.com>
On Thu, Dec 18, 2014 at 12:45 PM, Stefan Beller <sbeller@google.com> wrote:
> From: Ronnie Sahlberg <sahlberg@google.com>
>
> Update receive-pack to use an atomic transaction iff the client negotiated
> that it wanted atomic-push. This leaves the default behavior to be the old
> non-atomic one ref at a time update. This is to cause as little disruption
> as possible to existing clients. It is unknown if there are client scripts
> that depend on the old non-atomic behavior so we make it opt-in for now.
>
> If it turns out over time that there are no client scripts that depend on the
> old behavior we can change git to default to use atomic pushes and instead
> offer an opt-out argument for people that do not want atomic pushes.
>
> Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
> diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
> index e76e5d5..4952d91 100644
> --- a/builtin/receive-pack.c
> +++ b/builtin/receive-pack.c
> @@ -1059,6 +1063,16 @@ static void execute_commands(struct command *commands,
> return;
> }
>
> + if (use_atomic) {
> + transaction = ref_transaction_begin(&err);
Repeating from my earlier review[1]: If the 'pre-receive' hook
"declines", then this transaction is left dangling (and its resources
leaked).
> + if (!transaction) {
> + error("%s", err.buf);
> + strbuf_release(&err);
> + for (cmd = commands; cmd; cmd = cmd->next)
> + cmd->error_string = "transaction error";
The !use_atomic case (below), calls this error "failed to start
transaction", not merely "transaction error".
Furthermore, in the use_atomic case (also below), when a commit fails,
you assign err.buf to cmd->error_string rather than a generic
"transaction error" message. What differs between these cases which
makes the generic message preferable here over the more specific
err.buf message?
> + return;
> + }
> + }
> data.cmds = commands;
> data.si = si;
> if (check_everything_connected(iterate_receive_command_list, 0, &data))
> @@ -1087,7 +1101,30 @@ static void execute_commands(struct command *commands,
> if (cmd->skip_update)
> continue;
>
> + if (!use_atomic) {
> + transaction = ref_transaction_begin(&err);
> + if (!transaction) {
> + rp_error("%s", err.buf);
> + strbuf_release(&err);
> + cmd->error_string = "failed to start transaction";
> + continue;
> + }
> + }
> cmd->error_string = update(cmd, si);
> + if (!cmd->error_string) {
> + if (!use_atomic
> + && ref_transaction_commit(transaction, &err)) {
> + ref_transaction_free(transaction);
Repeating from my earlier review[1]: This is leaking 'transaction' for
each successful commit (and only freeing it upon commit error).
> + rp_error("%s", err.buf);
> + strbuf_release(&err);
> + cmd->error_string = "failed to update ref";
> + }
> + } else if (use_atomic) {
> + goto atomic_failure;
See commentary below.
> + } else {
> + ref_transaction_free(transaction);
> + }
> +
> if (shallow_update && !cmd->error_string &&
> si->shallow_ref[cmd->index]) {
> error("BUG: connectivity check has not been run on ref %s",
> @@ -1096,10 +1133,28 @@ static void execute_commands(struct command *commands,
> }
> }
>
> + if (use_atomic) {
> + if (ref_transaction_commit(transaction, &err)) {
> + rp_error("%s", err.buf);
> + for (cmd = commands; cmd; cmd = cmd->next)
> + cmd->error_string = err.buf;
At the end of this function, strbuf_release(&err) is invoked, which
leaves all these cmd->error_strings dangling.
> + }
> + ref_transaction_free(transaction);
> + }
> if (shallow_update && !checked_connectivity)
> error("BUG: run 'git fsck' for safety.\n"
> "If there are errors, try to remove "
> "the reported refs above");
> + strbuf_release(&err);
> +
> + return;
> +
> +atomic_failure:
> + for (cmd = commands; cmd; cmd = cmd->next)
> + if (!cmd->error_string)
> + cmd->error_string = "atomic push failure";
> +
> + ref_transaction_free(transaction);
goto's can help simplify error-handling when multiple conditional
branches need to perform common cleanup, however, this label
corresponds to only a single goto statement. Placing the cleanup code
for that one case so far away from the point where the condition is
detected actually obfuscates the code slightly rather than clarifying
it. It would be a bit easier to understand the logic if this cleanup
(plus a 'return') was inlined directly at the location of the 'goto'.
By the way, you employ the idiom of iterating over 'commands' and
assigning error_string often enough, that it might be worthwhile to
wrap it in a function. In that case, inlining the above cleanup code
in place of the 'goto' would make it even easier to read since it
would be a mere two-liner.
> }
[1]: http://article.gmane.org/gmane.comp.version-control.git/261455
next prev parent reply other threads:[~2014-12-18 22:27 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-12-15 19:56 [PATCH 0/5] Add a flag to push atomically Stefan Beller
2014-12-15 19:56 ` [PATCH 1/5] receive-pack.c: add protocol support to negotiate atomic-push Stefan Beller
2014-12-15 20:53 ` Junio C Hamano
2014-12-15 22:30 ` Stefan Beller
2014-12-15 19:56 ` [PATCH 2/5] send-pack.c: add an --atomic-push command line argument Stefan Beller
2014-12-15 21:01 ` Junio C Hamano
2014-12-15 19:56 ` [PATCH 3/5] receive-pack.c: use a single ref_transaction for atomic pushes Stefan Beller
2014-12-15 21:37 ` Junio C Hamano
2014-12-15 19:56 ` [PATCH 4/5] push.c: add an --atomic-push argument Stefan Beller
2014-12-15 21:50 ` Junio C Hamano
2014-12-15 19:56 ` [PATCH 5/5] t5543-atomic-push.sh: add basic tests for atomic pushes Stefan Beller
2014-12-15 22:29 ` Junio C Hamano
2014-12-15 22:33 ` [PATCH 0/5] Add a flag to push atomically Junio C Hamano
2014-12-16 18:49 ` [PATCHv2 1/6] receive-pack.c: add protocol support to negotiate atomic-push Stefan Beller
2014-12-16 18:49 ` [PATCHv2 2/6] send-pack: Invert the return value of ref_update_to_be_sent Stefan Beller
2014-12-16 19:14 ` Junio C Hamano
2014-12-16 18:49 ` [PATCHv2 3/6] send-pack.c: add --atomic command line argument Stefan Beller
2014-12-16 19:31 ` Junio C Hamano
2014-12-16 18:49 ` [PATCHv2 4/6] receive-pack.c: use a single ref_transaction for atomic pushes Stefan Beller
2014-12-16 19:29 ` Eric Sunshine
2014-12-16 20:30 ` Eric Sunshine
2014-12-16 19:35 ` Junio C Hamano
2014-12-16 18:49 ` [PATCHv2 5/6] push.c: add an --atomic-push argument Stefan Beller
2014-12-16 19:33 ` Eric Sunshine
2014-12-16 20:43 ` Junio C Hamano
2014-12-16 19:36 ` Junio C Hamano
2014-12-16 18:49 ` [PATCHv2 6/6] t5543-atomic-push.sh: add basic tests for atomic pushes Stefan Beller
2014-12-16 19:14 ` [PATCH] receive-pack: refuse all commands if one fails in atomic mode Stefan Beller
2014-12-16 20:32 ` Junio C Hamano
2014-12-16 19:37 ` [PATCHv2 6/6] t5543-atomic-push.sh: add basic tests for atomic pushes Eric Sunshine
2014-12-16 19:46 ` Junio C Hamano
2014-12-16 19:57 ` Stefan Beller
2014-12-16 20:46 ` Junio C Hamano
2014-12-16 20:51 ` Stefan Beller
2014-12-16 20:30 ` Junio C Hamano
2014-12-16 20:36 ` Stefan Beller
2014-12-16 19:05 ` [PATCHv2 1/6] receive-pack.c: add protocol support to negotiate atomic-push Junio C Hamano
2014-12-17 18:32 ` [PATCHv3 0/6] atomic pushes Stefan Beller
2014-12-17 18:32 ` [PATCHv3 1/6] receive-pack.c: add protocol support to negotiate atomic Stefan Beller
2014-12-19 1:05 ` Eric Sunshine
2014-12-17 18:32 ` [PATCHv3 2/6] send-pack: Rename ref_update_to_be_sent to check_to_send_update Stefan Beller
2014-12-17 22:53 ` Junio C Hamano
2014-12-17 18:32 ` [PATCHv3 3/6] send-pack.c: add --atomic command line argument Stefan Beller
2014-12-17 23:14 ` Junio C Hamano
2014-12-19 1:22 ` Eric Sunshine
2014-12-17 18:32 ` [PATCHv3 4/6] receive-pack.c: use a single ref_transaction for atomic pushes Stefan Beller
2014-12-17 23:26 ` Junio C Hamano
2014-12-17 23:58 ` Stefan Beller
2014-12-18 17:02 ` Junio C Hamano
2014-12-18 17:45 ` [PATCHv4 " Stefan Beller
2014-12-18 22:26 ` Eric Sunshine [this message]
2014-12-19 0:22 ` [PATCHv5 " Stefan Beller
2014-12-19 10:14 ` Eric Sunshine
2014-12-17 18:32 ` [PATCHv3 5/6] push.c: add an --atomic argument Stefan Beller
2014-12-19 1:29 ` Eric Sunshine
2014-12-17 18:32 ` [PATCHv3 6/6] t5543-atomic-push.sh: add basic tests for atomic pushes Stefan Beller
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=CAPig+cS9hJBga7BU-YC3bNG23Tb30kQsXydwGyRYb1T_0fiVqw@mail.gmail.com \
--to=sunshine@sunshineco.com \
--cc=git@vger.kernel.org \
--cc=jrnieder@gmail.com \
--cc=mhagger@alum.mit.edu \
--cc=ronniesahlberg@gmail.com \
--cc=sahlberg@google.com \
--cc=sbeller@google.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;
as well as URLs for NNTP newsgroup(s).