Mercurial socket interface

Bill Barry after.fallout at gmail.com
Sun Oct 4 14:34:05 UTC 2009


The recent Java thread got me thinking... much of the reason people do 
not like integrating Hg is because they don't want to use the CLI. There 
are several reasons for this:

1. Many languages make CLI execution unnecessarily complex (for example 
in C# it is about a page of code to do a system() call and read the 
output and error streams).
2. CLI execution is error prone because of the usage of "magic" strings.
3. CLI execution requires the parsing of both output and error streams.
4. Some command output is rather difficult to parse.
5. Every time you call Hg you run all the initialization code and 
cleanup code, increasing overhead for the actual command (potentially by 
a rather large percentage).


Most [all?] of these issues could be overcome with a combination of:
1. A socket interface running a daemon-ized version of Hg.
2. A library in the user's language of choice for interacting with the 
socket.

I think it should be up to the people who want to use Hg in their 
applications to write these libraries (they can band together to do it, 
we shouldn't care as far as this mailing list goes), but it should be 
our problem to create and maintain this socket interface.

A socket interface wouldn't require any changes to core Hg, all the 
following would be do-able via an extension or simply an external script 
(I think):
* new command "hg daemon" starts the socket interface (print port 
number, just print port number if an interface is already started for 
the repo?)
* new command "hg enddaemon" shuts down socket interface
The daemon would accept the hg CLI on its input channel (any regular hg 
command, simply split on spaces and call dispatch(args) unless inside 
quotes or preceded with \ and remove quotes unless quote preceded with \ 
[do not treat \" as a quote char]; possibly consider a different escape 
char like ` for ease of use on windows) and would write all output to 
the socket as if the command were run in the root directory of the repo 
at the command line. An external script wouldn't be very efficient 
because it would cause an instance of hg to load each time (parsing the 
hgrc and loading extensions for every command), but an extension could:
1. let hg load and configure
2. inside daemon command:
2.0. start a socket interface, print connection information
2.1. wait for input
2.2. on input loop:
2.2.1. split line according to spaces and quotes and escape char
2.2.2. execute lines 392 to 460 of dispatch.py (from "    cmd, func, 
args, options, cmdoptions = _parse(lui, args)" to "    return 
runcommand(lui, repo, cmd, fullargs, ui, options, d)"), outputting to 
socket (do you even need to run all of that or could you disallow the 
norepo commands and simplify because you already have a repo object)
2.2.3. undo changes made to ui in step 2.2.2
3. inside enddaemon command send a signal for daemon to finish current 
connection(s) and close

This could be made more complex, daemon could do something like open a 
port per connection, etc. It seems like this extension should be part of 
core Mercurial because it would be tied to the internals of dispatch.py, 
I believe that if this route is taken and supported there very well 
could be threading issues and/or memory leaks and because if such an 
interface were implemented it would probably be best to support it as a 
documented part of the core Hg API. I think that by writing a simple 
script, we could execute all of the Hg tests over the daemon interface 
so there wouldn't be any need to write test cases twice and that such a 
script should allow us to find memory issues (I expect threading issues 
would be far more difficult to decipher, but perhaps they could be 
ignored by making the daemon only have a single connection allowed at a 
time).

I considered entering an enhancement into bts but decided it should 
probably be discussed first.



Notice: I've never written anything like this before and likely have 
said some things above which are just plain wrong. Please correct my 
errored ways or send me to the waiting padded room if I've gone nuts.



More information about the Mercurial-devel mailing list