server bootstrapping upon connection (WARNING: LONG)

Benjamin Han this at is.for.spambot
Tue Feb 10 16:36:12 EST 2004


On 2004-02-10 13:46:37 -0500, ralf at brainbot.com said:

> fortepianissimo at yahoo.com.tw (Fortepianissimo) writes:
>> The problem: I need to prevent multiple copies of the server being
>> started. I did this by using file locking (fcntl.lockf()). However,
>> not every time the code successfully prevented the server being
>> started up more than one time. Here is the relevant code:
> 
> When using fcntl.lockf different FooClient instances in the same
> process will be able lock the file and start another server. You could
> either use fcntl.flock to prevent that or use some global flag.

Hm... I didn't know there's a difference between flock() and lockf(), 
and I didn't get much info from the document either. Could you explain 
a bit on why lockf() would not lock the file?

Actually I wrote a tiny script just to test if lockf() does what it 
claims to do:

--- CODE STARTS ---
#!/usr/bin/env python

import os,fcntl,sys

print "* about to open flock.txt"
f=open('flock.txt','w')
print "* opened the file"
fcntl.lockf(f.fileno(),fcntl.LOCK_EX|fcntl.LOCK_NB)
print "* obtained the lock, enter your line below:"
l=sys.stdin.readline()
f.truncate()
f.write(l)
f.flush()
sys.stdin.readline()
f.close()

--- CODE ENDS ---

It seems it does lock the file? (Mac OS X 10.3.2).

> Also be sure to keep the file open by keeping a reference to it
> (i.e. self.serverStartLock=open(...)). For debugging purposes, remove 
> that 'if self.connect(): return' and
> I think you'll see much more servers being started.

--- CODE SNIPPET STARTS ---
class FooClient:
    def __init__ (self, startServer=True):
        """Connects to FooServer if it exists, otherwise starts it and 
connects to it"""
        self.connected=True
        if self.connect(): return
        elif not startServer:
            if FOO_CLIENT_DEBUG: log('connection failed 1')
            self.connected=False
            return
..
--- CODE SNIPPET ENDS ---

Well in that case every connection will try to start a server. Good 
point on keeping a reference to the lock file though - I'll add to it 
and see what happens.

>> 
>> From the log (when problem occurred) I see even *AFTER* the server was
>> started and accepted connections (several connections came and went
>> happily), a connection would come in and hit the "connection failed 1"
>> log line. This shouldn't have happened as the default value of
>> startServer for FooClient.__init__() is True. In the very same
> 
> Well, maybe too many connection attempts are pending...

I failed to see why this should affect the default value of the 
argument... if startServer is True (default), that log line should have 
never been reached.

Thanks!

Ben




More information about the Python-list mailing list