From: Stefan Beller <sbeller@google.com>
To: gitster@pobox.com
Cc: git@vger.kernel.org, Jens.Lehmann@web.de,
Stefan Beller <sbeller@google.com>
Subject: [PATCH 1/2] submodule--helper: initial clone learns retry logic
Date: Thu, 9 Jun 2016 12:06:36 -0700 [thread overview]
Message-ID: <20160609190637.21177-2-sbeller@google.com> (raw)
In-Reply-To: <20160609190637.21177-1-sbeller@google.com>
Each submodule that is attempted to be cloned, will be retried once in
case of failure after all other submodules were cloned. This helps to
mitigate ephemeral server failures and increases chances of a reliable
clone of a repo with hundreds of submodules immensely.
The choice of the priority queue is a bit miss-leading as we use it as a
standard queue, but the priority queue offers the best API to use.
Signed-off-by: Stefan Beller <sbeller@google.com>
---
builtin/submodule--helper.c | 40 +++++++++++++++++++++++++++++++++-------
1 file changed, 33 insertions(+), 7 deletions(-)
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index c7deb55..efb6759 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -12,6 +12,7 @@
#include "remote.h"
#include "refs.h"
#include "connect.h"
+#include "prio-queue.h"
static char *get_default_remote(void)
{
@@ -568,6 +569,12 @@ static int module_clone(int argc, const char **argv, const char *prefix)
return 0;
}
+static int compare_ce(const void *one, const void *two, void *cb_data)
+{
+ const struct cache_entry *ce_one = one, *ce_two = two;
+ return ce_two - ce_one;
+}
+
struct submodule_update_clone {
/* index into 'list', the list of submodules to look into for cloning */
int current;
@@ -590,10 +597,13 @@ struct submodule_update_clone {
/* If we want to stop as fast as possible and return an error */
unsigned quickstop : 1;
+
+ /* Queue of failed clones, containing the cache_entry */
+ struct prio_queue failed_queue;
};
#define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
SUBMODULE_UPDATE_STRATEGY_INIT, 0, -1, NULL, NULL, NULL, NULL, \
- STRING_LIST_INIT_DUP, 0}
+ STRING_LIST_INIT_DUP, 0, { compare_ce }}
static void next_submodule_warn_missing(struct submodule_update_clone *suc,
@@ -718,23 +728,36 @@ cleanup:
static int update_clone_get_next_task(struct child_process *child,
struct strbuf *err,
void *suc_cb,
- void **void_task_cb)
+ void **ce_task_cb)
{
struct submodule_update_clone *suc = suc_cb;
+ const struct cache_entry *ce;
for (; suc->current < suc->list.nr; suc->current++) {
- const struct cache_entry *ce = suc->list.entries[suc->current];
+ ce = suc->list.entries[suc->current];
if (prepare_to_clone_next_submodule(ce, child, suc, err)) {
+ *ce_task_cb = (struct cache_entry *) ce;
suc->current++;
return 1;
}
}
+ /*
+ * The loop above tried cloning each submodule once,
+ * now try the stragglers again.
+ */
+ ce = (struct cache_entry *) prio_queue_get(&suc->failed_queue);
+ if (ce) {
+ if (!prepare_to_clone_next_submodule(ce, child, suc, err))
+ die("BUG: ce was a submodule before?");
+ return 1;
+ }
+
return 0;
}
static int update_clone_start_failure(struct strbuf *err,
void *suc_cb,
- void *void_task_cb)
+ void *ce_task_cb)
{
struct submodule_update_clone *suc = suc_cb;
suc->quickstop = 1;
@@ -744,15 +767,18 @@ static int update_clone_start_failure(struct strbuf *err,
static int update_clone_task_finished(int result,
struct strbuf *err,
void *suc_cb,
- void *void_task_cb)
+ void *ce_task_cb)
{
struct submodule_update_clone *suc = suc_cb;
+ struct cache_entry *ce = ce_task_cb;
if (!result)
return 0;
- suc->quickstop = 1;
- return 1;
+ strbuf_addf(err, _("Failed to clone '%s'. Scheduled for retry"),
+ ce->name);
+ prio_queue_put(&suc->failed_queue, ce);
+ return 0;
}
static int update_clone(int argc, const char **argv, const char *prefix)
--
2.9.0.rc2.368.gdadd65c
next prev parent reply other threads:[~2016-06-09 19:07 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-09 19:06 [PATCH 0/2] Dealing with a lot of submodules Stefan Beller
2016-06-09 19:06 ` Stefan Beller [this message]
2016-06-09 19:19 ` [PATCH 1/2] submodule--helper: initial clone learns retry logic Junio C Hamano
2016-06-09 19:47 ` Stefan Beller
2016-06-09 19:59 ` Junio C Hamano
2016-06-09 20:40 ` Junio C Hamano
2016-06-09 23:38 ` Stefan Beller
2016-06-09 19:06 ` [PATCH 2/2] submodule update: continue when a clone fails 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=20160609190637.21177-2-sbeller@google.com \
--to=sbeller@google.com \
--cc=Jens.Lehmann@web.de \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.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).