[Twisted-Python] mktap/twistd make 2 copies of some objects? (was Re: [Twisted-web] subtle copying in woven driving me crazy.)

Douglas Bagnall douglas at paradise.net.nz
Thu Jan 15 06:36:26 EST 2004


A while ago in twisted-web, in a thread beginning here:

http://twistedmatrix.com/pipermail/twisted-web/2003-December/000061.html

I was complaining about twisted making a spare copy of an object used 
for guard credentials (meaning you can't add users on the fly).  I now 
think it stems from the pickling of objects between mktap and twistd. 
The checker is instantiated and pickled in mktap, because the guard code 
is called directly from updateApplication. But then when twistd runs, it 
is instantiated again for the rest of the app.

This makes two copies of my checker:

#!/bin/sh
kill `cat twistd.pid`
mktap2.3 upstage
twistd2.3  -f upstage.tap

and this doesn't:

#!/usr/bin/python
from upstage import app
from twisted.internet import reactor
app.updateApplication(reactor, {'webport':8083,'port':7232 })
reactor.run()


The code called in updateApplication goes a bit like this:

def updateApplication(app, options):
     docroot = website()
     app.listenTCP(webport, server.Site(docroot))

def website():
     docroot = static.File(config.HTDOCS)
     admin = adminWrapper(config.ADMIN)
     docroot.putChild('admin', admin)
     return docroot

class Checker(dict):
     __implements__ = checkers.ICredentialsChecker
     credentialInterfaces = (IUsernamePassword,)
     def requestAvatarId(self, credentials):
         player = self.get(credentials.username)
         if player and player.password == credentials.password:
             return credentials.username
         return failure.Failure(error.UnauthorizedLogin())

myCheckerThatGetsCopied = Checker({'p1': player1})

def adminWrapper(admin_dir):
     p = Portal(AdminRealm(admin_dir))
     p.registerChecker(AllowAnonymousAccess(), IAnonymous)
     p.registerChecker(myCheckerThatGetsCopied, IUsernamePassword)
     upw = guard.UsernamePasswordWrapper(p, callback=dumbRedirect)
     r = guard.SessionWrapper(upw)
     r.sessionLifetime = 12 * 3600
     return r


One workaround is wrapping the true checker in one that has no data:

class CheckerThatGetsCopiedWrapper:
     __implements__ = checkers.ICredentialsChecker
     credentialInterfaces = (credentials.IUsernamePassword,)

     def requestAvatarId(self, credentials):
         return myCheckerThatGetsCopied.requestAvatarId(credentials)


which is what I'm actually using now.  Is my diagnosis plausible?

regards,

douglas bagnall






More information about the Twisted-Python mailing list