[PATCH 1 of 5 RFC] serve: add --cmdserver option to communicate with hg over a pipe

Matt Mackall mpm at selenic.com
Fri Jun 3 16:07:23 CDT 2011


On Fri, 2011-06-03 at 23:04 +0300, Idan Kamara wrote:
> # HG changeset patch
> # User Idan Kamara <idankk86 at gmail.com>
> # Date 1307111261 -10800
> # Node ID 5b9901ab0f4c60450ecd5c112fd937493a043667
> # Parent  a67e866f46f9919a963afb4e4f1bb4a2c56a3c42
> serve: add --cmdserver option to communicate with hg over a pipe

> +class server(object):
> +    """
> +    Listens for commands on stdin, runs them and writes the output to stdout
> +    using 2 channels for stdout/err
> +    """
> +    def __init__(self, ui, repo, mode):
> +        self.ui = ui
> +        self.ui.setconfig('ui', 'interactive', 'off')
> +        self.repo = repo
> +
> +        if mode == 'pipe':
> +            # stream all output to stdout using 2 channels to distinguish them
> +            sys.stderr = channeledoutput(sys.stderr, sys.stdout, 'e')
> +            sys.stdout = channeledoutput(sys.stdout, sys.stdout, 'o')
> +            self.fin = sys.stdin
> +            self.fout = sys.stdout

Eventually we'll want to wrap up stderr/stdout in the dispatch request
object so that we're not monkeypatching the globals.

We probably want to stick in a way for the command server to say 'ready'
and advertise capabilities right off the bat so that we don't have to do
an ugly hack to get it later.

> +        else:
> +            raise util.Abort(_('unknown mode %s') % mode)
> +
> +        # Prevent insertion/deletion of CRs
> +        util.setbinary(self.fin)
> +        util.setbinary(self.fout)
> +
> +    def readargs(self):
> +        """ returns a list of arguments to execute, format:
> +
> +        length in bytes of args (int),
> +        NUL terminated list of strings
> +        """

We should document our encoding expectations, ie these are local
strings. Libraries will probably want a want to say "I like it when you
talk utf-8 to me".

> +        length = self.fin.read(4)
> +
> +        # is the other end closed?
> +        if not length:
> +            return None
> +
> +        length = struct.unpack('>I', length)[0]
> +        args = self.fin.read(length)
> +        return args.split('\0')

We probably want an arg[0] that says "command" so that we have a way to
send things that are not commands to the server. For instance, switching
encoding or switching HGPLAIN modes, etc.

> +    def writereturn(self, ret):
> +        """ write the return code - \0 followed by an integer """
> +        # ret could be None
> +        ret = ret or 0
> +        self.fout.write('\0' + struct.pack('>i', int(ret)))
> +        self.fout.flush()
> +
> +    def serve(self):
> +        while True:
> +            args = self.readargs()
> +            if not args:
> +                break
> +
> +            # copy the ui so changes to it don't persist between requests
> +            req = dispatch.request(args, self.ui.copy(), self.repo)
> +            ret = dispatch.dispatch(req)
> +
> +            self.writereturn(ret)
> +
> +        return None
> diff -r a67e866f46f9 -r 5b9901ab0f4c tests/test-debugcomplete.t
> --- a/tests/test-debugcomplete.t	Thu Jun 02 00:33:33 2011 +0200
> +++ b/tests/test-debugcomplete.t	Fri Jun 03 17:27:41 2011 +0300
> @@ -137,6 +137,7 @@
>    --accesslog
>    --address
>    --certificate
> +  --cmdserver
>    --config
>    --cwd
>    --daemon
> @@ -199,7 +200,7 @@
>    pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
>    push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
>    remove: after, force, include, exclude
> -  serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, templates, style, ipv6, certificate
> +  serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
>    status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
>    summary: remote
>    update: clean, check, date, rev
> diff -r a67e866f46f9 -r 5b9901ab0f4c tests/test-http-branchmap.t
> --- a/tests/test-http-branchmap.t	Thu Jun 02 00:33:33 2011 +0200
> +++ b/tests/test-http-branchmap.t	Fri Jun 03 17:27:41 2011 +0300
> @@ -79,7 +79,7 @@
>    > 
>    > myui = ui.ui()
>    > repo = hg.repository(myui, 'a')
> -  > commands.serve(myui, repo, stdio=True)
> +  > commands.serve(myui, repo, stdio=True, cmdserver=False)
>    > EOF
>    $ echo baz >> b/foo
>    $ hg -R b ci -m baz
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel


-- 
Mathematics is the supreme nostalgia of our time.




More information about the Mercurial-devel mailing list