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>,
Junio C Hamano <gitster@pobox.com>,
Ronnie Sahlberg <sahlberg@google.com>
Subject: Re: [PATCHv5 4/6] receive-pack.c: use a single ref_transaction for atomic pushes
Date: Fri, 19 Dec 2014 05:14:20 -0500 [thread overview]
Message-ID: <CAPig+cSqHW9MGsPW9DCFZ8_Xz+WUc1TBpih2xvPq1NSkJQMM5Q@mail.gmail.com> (raw)
In-Reply-To: <1418948521-30787-1-git-send-email-sbeller@google.com>
On Thu, Dec 18, 2014 at 7:22 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..ebce2fa 100644
> --- a/builtin/receive-pack.c
> +++ b/builtin/receive-pack.c
> @@ -1087,7 +1102,36 @@ 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 = "transaction failed to start";
> + continue;
For this failure, you 'continue' the loop.
> + }
> + }
> cmd->error_string = update(cmd, si);
> + if (!cmd->error_string) {
> + if (!use_atomic) {
> + if (ref_transaction_commit(transaction, &err)) {
> + rp_error("%s", err.buf);
> + strbuf_release(&err);
> + cmd->error_string = "failed to update ref";
However, for this failure, you fall through...
> + }
> + ref_transaction_free(transaction);
> + }
> + } else {
> + ref_transaction_free(transaction);
> + if (use_atomic) {
> + for (cmd = commands; cmd; cmd = cmd->next)
> + if (!cmd->error_string)
> + cmd->error_string = "atomic push failure";
> + strbuf_release(&err);
> + return;
> + }
> + }
> +
> if (shallow_update && !cmd->error_string &&
And here must check if an error occurred in some code above.
This is ugly and inconsistent, and feels as if the new code was
plopped into the middle of this function without concern for overall
flow, thus negatively impacting maintainability and readability. It
could be made a bit cleaner by either (1) consistently using
'continue' for the non-atomic error cases, or (2) moving the "shallow"
handling up into the conditional where you _know_ that no error has
occurred (error_string is NULL).
However, this issue is symptomatic of a larger problem. Prior to this
patch, execute_commands() was relatively straight-forward and easy to
read and understand. With the patch, and its interleaved atomic and
non-atomic cases, the logic flow is a mess: it places a high cognitive
load on the reader and is difficult to maintain and to do correctly in
the first place (as already evidenced).
Have you considered refactoring the code to implement the atomic and
non-atomic cases as distinct single-purpose helper functions of
execute_commands()? It should be possible to do so with very little
duplicated code between the two functions, and the result would likely
be much more readable and maintainable.
> si->shallow_ref[cmd->index]) {
> error("BUG: connectivity check has not been run on ref %s",
> @@ -1096,10 +1140,19 @@ 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 = "atomic transaction failed";
> + }
> + 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);
> }
>
> static struct command **queue_command(struct command **tail,
> --
> 2.2.1.62.g3f15098
next prev parent reply other threads:[~2014-12-19 10:14 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
2014-12-19 0:22 ` [PATCHv5 " Stefan Beller
2014-12-19 10:14 ` Eric Sunshine [this message]
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+cSqHW9MGsPW9DCFZ8_Xz+WUc1TBpih2xvPq1NSkJQMM5Q@mail.gmail.com \
--to=sunshine@sunshineco.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--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).