[Zope] Re: Running more than one instance on windows often block
each other
Sune B. Woeller
sune at syntetisk.dk
Sat Jul 30 03:48:51 EDT 2005
Tim Peters wrote:
> The attached hasn't failed on my box (Win XP Pro SP2, Python 2.3.5)
> for about two hours, running it in 3 processes. Was using 2 processes
> before; discovered it was much easier to provoke problems using 3; but
> the # of ephemeral ports in use increases too, typically hovering
> between 7-8 thousand after reaching steady state.
>
> I'll let it run the rest of today, and start changing ZODB code if it
> still looks good. I hope someone(s) else will then volunteer to port
> the Windows changes to all the copies of Medusa code in the various
> active Zope trunks and branches.
I have been running 8 simultaneous processes with socktest29() for
12 hours, on my xp box. No problems except for an occasional "Address already in
use".
>
> This suffers from what I still believe to be bugs in the Windows
> socket implementation, but there is only one symptom I see with this,
> and the code uses try/except to implement what appears to be a
> reliable workaround.
>
> import socket, errno
> import time, random
>
> class BindError(Exception):
> pass
>
> def socktest29():
> w = socket.socket()
>
> # Disable buffering -- pulling the trigger sends 1 byte,
> # and we want that sent immediately, to wake up asyncore's
> # select() ASAP.
> w.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
>
> count = 0
> while 1:
> count += 1
> # Bind to a local port; for efficiency, let the OS pick
> # a free port for us.
> # Unfortunately, stress tests showed that we may not
> # be able to connect to that port ("Address already in
> # use") despite that the OS picked it. This appears
> # to be a race bug in the Windows socket implementation.
> # So we loop until a connect() succeeds (almost always
> # on the first try).
> a = socket.socket()
> a.bind(("127.0.0.1", 0))
> print 'b',
> connect_address = a.getsockname() # assigned (host, port) pair
> a.listen(1)
> try:
> w.connect(connect_address)
> print 'c',
> break
> except socket.error, detail:
> if detail[0] != errno.WSAEADDRINUSE:
> # "Address already in use" is the only error
> # I've seen on two WinXP Pro SP2 boxes, under
> # Pythons 2.3.5 and 2.4.1.
> raise
> # (10048, 'Address already in use')
> # assert count <= 2 # never triggered in Tim's tests
> if count >= 10: # I've never seen it go above 2
> a.close()
> w.close()
> raise BindError("Cannot bind trigger!")
> # Close `a` and try again. Note: I originally put a short
> # sleep() here, but it didn't appear to help or hurt.
> print
> print detail, a.getsockname()
> a.close()
>
> r, addr = a.accept() # r becomes asyncore's (self.)socket
> print 'a',
> a.close()
> print 'c',
>
> return (r, w)
>
> sofar = []
> try:
> while 1:
> print '.',
> stuff = socktest29()
> sofar.append(stuff)
> time.sleep(random.random()/10)
> if len(sofar) == 50:
> tup = sofar.pop(0)
> r, w = tup
> msg = str(random.randrange(1000000))
> w.send(msg)
> msg2 = r.recv(100)
> assert msg == msg2, (msg, msg2, r.getsockname(), w.getsockname())
> r.close()
> w.close()
> except KeyboardInterrupt:
> for tup in sofar:
> for s in tup:
> s.close()
> _______________________________________________
> Zope maillist - Zope at zope.org
> http://mail.zope.org/mailman/listinfo/zope
> ** No cross posts or HTML encoding! **
> (Related lists -
> http://mail.zope.org/mailman/listinfo/zope-announce
> http://mail.zope.org/mailman/listinfo/zope-dev )
>
More information about the Zope
mailing list