chgserver: add an explicit "reconnect" instruction to validate
In some rare cases (next patch), we may want validate to do "unlink" without
forcing the client reconnect. This patch addes a new "reconnect" instruction
and makes "unlink" not to reconnect by default.
--- a/contrib/chg/chg.c Mon Mar 14 11:06:34 2016 +0000
+++ b/contrib/chg/chg.c Mon Mar 14 13:48:33 2016 +0000
@@ -444,9 +444,14 @@
abortmsg("failed to prepare pager (errno = %d)", errno);
}
-/* Run instructions sent from the server like unlink and set redirect path */
-static void runinstructions(struct cmdserveropts *opts, const char **insts)
+/* Run instructions sent from the server like unlink and set redirect path
+ * Return 1 if reconnect is needed, otherwise 0 */
+static int runinstructions(struct cmdserveropts *opts, const char **insts)
{
+ int needreconnect = 0;
+ if (!insts)
+ return needreconnect;
+
assert(insts);
opts->redirectsockname[0] = '\0';
const char **pinst;
@@ -460,15 +465,19 @@
"%s", *pinst + 9);
if (r < 0 || r >= (int)sizeof(opts->redirectsockname))
abortmsg("redirect path is too long (%d)", r);
+ needreconnect = 1;
} else if (strncmp(*pinst, "exit ", 5) == 0) {
int n = 0;
if (sscanf(*pinst + 5, "%d", &n) != 1)
abortmsg("cannot read the exit code");
exit(n);
+ } else if (strcmp(*pinst, "reconnect") == 0) {
+ needreconnect = 1;
} else {
abortmsg("unknown instruction: %s", *pinst);
}
}
+ return needreconnect;
}
/*
@@ -542,10 +551,10 @@
abortmsg("cannot open hg client");
hgc_setenv(hgc, envp);
const char **insts = hgc_validate(hgc, argv + 1, argc - 1);
- if (insts == NULL)
+ int needreconnect = runinstructions(&opts, insts);
+ free(insts);
+ if (!needreconnect)
break;
- runinstructions(&opts, insts);
- free(insts);
hgc_close(hgc);
if (++retry > 10)
abortmsg("too many redirections.\n"
--- a/contrib/chg/hgclient.c Mon Mar 14 11:06:34 2016 +0000
+++ b/contrib/chg/hgclient.c Mon Mar 14 13:48:33 2016 +0000
@@ -478,8 +478,8 @@
*
* @return - NULL, the server believes it can handle our request, or does not
* support "validate" command.
- * - a list of strings, the server cannot handle our request and it
- * sent instructions telling us how to fix the issue. See
+ * - a list of strings, the server probably cannot handle our request
+ * and it sent instructions telling us what to do next. See
* chgserver.py for possible instruction formats.
* the list should be freed by the caller.
* the last string is guaranteed to be NULL.
--- a/hgext/chgserver.py Mon Mar 14 11:06:34 2016 +0000
+++ b/hgext/chgserver.py Mon Mar 14 13:48:33 2016 +0000
@@ -427,10 +427,16 @@
An instruction string could be either:
- "unlink $path", the client should unlink the path to stop the
outdated server.
- - "redirect $path", the client should try to connect to another
- server instead.
+ - "redirect $path", the client should attempt to connect to $path
+ first. If it does not work, start a new server. It implies
+ "reconnect".
- "exit $n", the client should exit directly with code n.
This may happen if we cannot parse the config.
+ - "reconnect", the client should close the connection and
+ reconnect.
+ If neither "reconnect" nor "redirect" is included in the instruction
+ list, the client can continue with this server after completing all
+ the instructions.
"""
args = self._readlist()
try:
@@ -445,6 +451,7 @@
if newhash.mtimehash != self.hashstate.mtimehash:
addr = _hashaddress(self.baseaddress, self.hashstate.confighash)
insts.append('unlink %s' % addr)
+ insts.append('reconnect')
if newhash.confighash != self.hashstate.confighash:
addr = _hashaddress(self.baseaddress, newhash.confighash)
insts.append('redirect %s' % addr)