[Python-Dev] asyncore fixes in Python 2.6 broke Zope's version of medusa

Tres Seaver tseaver at palladion.com
Thu Oct 9 18:08:23 CEST 2008


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Guido van Rossum wrote:
> On Wed, Oct 8, 2008 at 6:39 PM, Bill Janssen <janssen at parc.com> wrote:
>> Josiah Carlson <josiah.carlson at gmail.com> wrote:
>>
>>> But yes, zope needs to be changed to reflect the updated
>>> asyncore/asynchat semantics.  Trust me; it's faster, cleaner, and
>>> easier to use now.
>> Just for completeness, I built a fresh 2.6, installed Medusa (from
>> http://www.amk.ca/python/code/medusa.html), and it runs just fine (well,
>> as well as it does on 2.5, anyway).  I think this is a Zope issue.
> 
> Way back in the day, Zope monkeypatched whole parts of asyncore,
> replacing them with some of its own code. If that's still the case,
> this breakage should be no surprise.

Zope has been hooking the 'asyncore.loop' function (wrapping it in order
to add a "clean shutdown' flog) since 2001 at least (the 2.5 branch is
the earliest checkout I have, and it was branched in early January 2002).

Zope also began patched asyncore's logging functions in 2.7, and later
updated that patch to make the logger use the stdlib 'logging' module.

I think the change we need to make (in ZServer/medusa/http_server.py) is
to emulate the new 'writeable' implementation in asynchat, at least when
running under 2.6.

Zope's 'ZServer.medusa.http_server.http_request.writable()'
implementation is::

    def writable (self):
        # this is just the normal async_chat 'writable',
        # here for comparison
        return self.ac_out_buffer or len(self.producer_fifo)


The Python 2.5 asynchat.asynchat.writable does::

    def writable (self):
        "predicate for inclusion in the writable for select()"
        # return len(self.ac_out_buffer) or len(self.producer_fifo) or
        # (not self.connected)
        # this is about twice as fast, though not as clear.
        return not (
                (self.ac_out_buffer == '') and
                self.producer_fifo.is_empty() and
                self.connected
                )

The Python 2.6 asynchat.asynchat.writable now does::

    def writable (self):
        "predicate for inclusion in the writable for select()"
        return self.producer_fifo or (not self.connected)


medusa 0.5.4's medusa.http_server.http_request doesn't override
'writable', but it does have a broken 'writeable_for_proxy':


    def writable_for_proxy (self):
        # this version of writable supports the idea of a 'stalled'
        # producer
        # [i.e., it's not ready to produce any output yet] This is
        # needed by
        # the proxy, which will be waiting for the magic combination of
        # 1) hostname resolved
        # 2) connection made
        # 3) data available.
        if self.ac_out_buffer:
            return 1
        elif len(self.producer_fifo):
            p = self.producer_fifo.first()
            if hasattr (p, 'stalled'):
                return not p.stalled()
            else:
                return 1


Tres.
- --
===================================================================
Tres Seaver          +1 540-429-0999          tseaver at palladion.com
Palladion Software   "Excellence by Design"    http://palladion.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFI7ix3+gerLs4ltQ4RAldnAKC/QLJHmdE9dxInkWuIGja0gtSXYwCcCJcH
6XooEwW/AkJ1ntmGyxi8urM=
=1kps
-----END PGP SIGNATURE-----



More information about the Python-Dev mailing list