David Marker wrote:
> Richard Lowe wrote:
>   
>> David Marker <David.Marker at Sun.COM> writes:
>>
>> [...]
>>   
>>     
>>> I've given locking some thought. And I think that is more grim than
>>> having 2 repos.  You can easily end up with a locked gate until I
>>> come along and notice its stuck because you can't trap the abort
>>> from Mercurial when a pretxnchangegroup hook either returns non-zero
>>> OR raises an exception. So if something bad happens in sanity.py (an
>>> exception I didn't account for) you get rolled back. But the lock is
>>> not getting cleared.
>>>     
>>>       
>> You can detect a stale lock however.
>>
>> lock file == symlink to destination hg-$HGUSER.$PID
>>
>> If you come to the lock and would block, check that $PID is still
>> around...
>>   
>>     
>
> Well, now I feel kinda silly. That seems quite workable...
> Course I'll just have to add that to my list of things to do though.
>
> So we can do the sleep a bit check if there is a lockfile still.
> If there is make sure that PID is around. If not blow away lock
> and continue. Probably write something to ui to let them know
> they aren't hung...
>
> Current lock is just the big gk lock everybody out kinda lock.
> With the ability to let just one person push (say for massive
> project).
>
> There I thought my TODO list was shrinking...
>
> -dvd
>   

Urgh. On further reflection I'm still pretty sure it won't work.
Already discussed a bit with Rich.

Here is a pastebin link of the problem (also added below but if your 
mail client
doesn't have fixed width it will look ugly):
    http://pastebin.com/m10c38176

The dashed lines are context switches.

For a moment or two there I thought that maybe if the process doing the
pull cached the changelog before checking for the "push-lock" it would
be OK. But (a) it doesn't, and (b) if it did that would probably cause
hg to crash when it tried to read files that a rollback truncated. Or at
least defeat the whole purpose of bothering with a lock.

So it really seems to come down to pretxnchangegroup hooks imply
you have a repository that is push only and a second repository that
is pull only. The push only repo can move a validated push to the
pull only repo (which doesn't need any check beyond "did it come
from the push-only repo?" which incidentally can be checked in
prechangegroup safely). So there would never be a race with the
pull only repo. No matter what point in time your pull reads the
changelog it is valid.

Now as we intend to have a clone anyway... perhaps the correct thing
is to say the new Mercurial clone isn't just updated at 11PM Pacific.
Rather it is constantly updated with successful pushes to the gate
(which nobody is allowed to pull from). Making it the pull repo.

That may cause heartburn because now gatelings who want just
"yesterdays" bits need to do:
    hg log -R clone-repo -d "<valid hg datestring" -l 1
Then pull over to that revision.

But do they really want 11PM source? I mean we've always had
a clone mostly to give gatelings a place they can get reasonably
current source that won't interfere with others trying to putback.

But I'm not seeing a way out of the hook window that doesn't involve
two repositories. If anybody else knows a way please chime in.

-dvd


Process A (pull)          | Process B (push)
--------------------------+--------------------------
(1) checks for push lock  |
    in preoutgoing.       |
    doesn't see it        |
--------------------------+--------------------------
                          | (2) sets push lock
                          |     in prechangegroup
                          | (3) starts running
                          |     pretxnchangegroup
                          |     hooks
--------------------------+--------------------------
(4) sends cstes including |
    csets from (B)        |
--------------------------+--------------------------
                          | (5) a pretxnchangegroup
                          |     hook fails
                          |     rollback

Reply via email to