Mercurial > hg
changeset 28535:aa082a8125da
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.
author | Jun Wu <quark@fb.com> |
---|---|
date | Mon, 14 Mar 2016 13:48:33 +0000 |
parents | 293adbaa14a7 |
children | a979f5b03320 |
files | contrib/chg/chg.c contrib/chg/hgclient.c hgext/chgserver.py |
diffstat | 3 files changed, 25 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- 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)