pretxnchangegroup hook fails because it can't acquire lock

Simon King simon at simonking.org.uk
Tue Nov 5 21:56:04 UTC 2013


On Tue, Nov 5, 2013 at 9:48 PM, Mick Jordan <mick.jordan at oracle.com> wrote:
> On 11/5/13 1:40 PM, Simon King wrote:
>>
>> On Tue, Nov 5, 2013 at 7:50 PM, Mick Jordan <mick.jordan at oracle.com>
>> wrote:
>>>
>>> On 11/5/13 3:41 AM, Simon King wrote:
>>>>
>>>> [hooks] pretxnchangegroup.push =
>>>> python:/path/to/hook/script.py:pushwhilelocked
>>>
>>>
>>>> Hope that helps, Simon
>>>
>>> I have this working now, just one small problem that someone might know
>>> the
>>> answer to, which is that the hgweb script is evidently returning a bad
>>> header. It's nice that all the python logging shows up now in the server
>>> error_log Here are the salient lines:
>>>
>>> [Tue Nov 05 11:31:25 2013] [error] [client ...] abort:
>>> pretxnchangegroup.run_gate hook failed
>>> [Tue Nov 05 11:31:25 2013] [error] [client ...] malformed header from
>>> script. Bad header=listing keys for "bookmarks": hgweb.cgi
>>>
>>>
>> At a guess, your hook is producing some output on stdout. Since you
>> are using CGI, stdout from the script becomes part of the HTTP
>> response.
>
> Indeed, rather a lot I am afraid. But it's useful debugging info, so is
> there a correct way to do that which doesn't become part of the response?
>

I'm not aware of any way when you are using CGI, no. The way CGI
scripts work is that the web server calls the CGI script with a
certain set of environment variables, and passes any request body from
the client to the stdin of the CGI script. Whatever the CGI script
returns on stdout becomes the HTTP response.

The "correct" thing to do would be to ensure that your debugging info
goes to stderr rather than stdout. I think it will then end up in the
web server logs.


>>
>> So you need to prevent your hook from outputting to stdout. If it were
>> an out-of-process hook, you could do this using standard shell
>> redirection operators, but for an in-process hook you'll have to do
>> something different. Completely untested, but you might be able to do
>> something like this:
>>
>> import sys
>>
>> def myhook(ui, repo, **kwargs):
>>      oldstdout = sys.stdout
>>      try:
>>          sys.stdout = sys.stderr
>>          do_stuff()
>>      finally:
>>          sys.stdout = oldstdout
>>
>>
>> If you have the option, it might be better to use WSGI rather than CGI
>> to host hgweb. The performance should be better, and it wouldn't have
>> problems like this.
>>
>>
> I looked at WSGI this morning, but I have to build it from source for my
> version of Linux/Apache. I'll get to that, but why would it avoid the output
> problem?
>

WSGI applications don't communicate with the web server over stdin and
stdout, so it doesn't matter if the app happens to write to stdout.

Simon



More information about the Mercurial mailing list