[Twisted-Python] PB and multiple apps
Jeff Grimmett
grimmtooth at softhome.net
Thu Feb 13 19:20:30 EST 2003
> It's not at all clear to me what you're doing. Can you post
> some code?
I'll try to explain in more detail since the source is a mess right now
with all the commented code etc. With snippets.
App 1: it's a debugging window that I can run or not as needed. When it
is up it receives messages from the other app and feeds them to my
wxApp.
import sys
from myLib import *
from twisted.internet import app
from twisted.internet import wxsupport
from twisted.spread import pb
# wx app stuff trimmed for brevity.
# The handler for incoming remote calls.
# I pass it a reference to my wxApp's top frame.
class DBHandler(pb.Root):
def __init__ (self, win):
self.Commands = {'Msg' : self.doMsg,
'Ping' : self.doPing
}
self.win = win
# This is the function registered with Debug.Debug() (below)
def remote_DoCommand(self, msg):
if msg['Command'] in self.Commands:
return(apply(self.Commands[msg['Command']], [msg]))
else:
return(-1)
# Log a message
def doMsg(self, msg):
self.win.LogIt(msg['Msg'])
return(0)
# Return a ping.
def doPing(self, msg):
return(1)
# Here's where I set up the app and run it
def RunServer(args):
# Set up the wxApp
myWXApp = MyApp(0)
# Replace the wx event loop with the twisted
# event loop and adds wx event handling.
wxsupport.install(myWXApp)
# Our PB factory
ctl = pb.BrokerFactory(DBHandler(myWXApp.frame))
# And set up the app
myApp = app.Application("Debug")
myApp.listenTCP(Debug.DBPort, ctl)
myApp.run(save=0)
sys.exit(0)
if __name__ == "__main__":
RunServer(sys.argv)
## Following is the library code that is used by the other app
## to send debugging info to the debugger.
From twisted.internet import reactor
from twisted.spread import pb
import time
DBPort = 7747
Me = Entities['Debugger'] # def for Entities not included for brevity
# This is a very lame bucket to hold data in a dynamic way
# so that the data can be passed back and forth between functions.
# Needs to be replaced with something a bit slicker.
class Bucket:
def __init__(self, msg):
self.SetMsg(msg)
self.SetRC(-1)
def SetMsg(self, msg):
self.msg = msg
def GetMsg(self):
return(self.msg)
def SetRC(self, rc):
self.rc = rc
def GetRC(self):
return(self.rc)
bucky = Bucket('')
# Following three functions are PB functions. Based on twisted example
# code.
def gotObject(object):
object.callRemote ( "DoCommand", {'Command': 'Msg',
'Msg':bucky.GetMsg()}).addCallback(gotCommand)
def gotCommand(rc):
bucky.SetRC(rc)
reactor.stop()
# This fires if we don't manage to connect.
def gotNoObject(reason):
bucky.SetRC(-1)
reactor.stop()
# Sets up the debugging session and returns response
def Debug(ID, msg):
if ID == 0:
return(-1)
txt = '%s :: [%s] %s' % ( time.strftime('%Y.%m.%d %H:%M:%S'),
ID, msg
)
bucky.SetMsg(txt)
pb.getObjectAt("localhost", DBPort, 30).addCallbacks(gotObject,
gotNoObject)
reactor.run()
return(bucky.GetRC())
The other app is very similar to the above, with a similar library that
passes slightly different data around. The key difference is that the
other app has calls to Debug.Debug() within the handler itself. Here is
the handler:
class CtlHandler(pb.Root):
def __init__ (self):
self.Commands = { 'Shutdown' : self.doShutdown
}
def remote_DoCommand(self, msg):
print msg
# THIS IS WHERE IT DIES
Debug.Debug (Me, "Received Control message [%s] from [%s]" % (
msg['Command'], msg['From'] ) )
# If I remove the above, all works well. If I don't, this app
# closes.
if msg['Command'] in self.Commands:
return(apply(self.Commands[msg['Command']], [msg]))
else:
Debug.Debug(Me, "**** Unknown Control message [%s]!" %
msg['Command'])
return({'Status':'Unknown Command', 'RC':-1})
def doShutdown(self, msg):
Debug.Debug(Me, "***** CONTROL SHUTTING DOWN IN 3 SECONDS")
reactor.callLater(20, self.endShutdown)
return({'Status':'OK', 'RC':0})
def endShutdown(self):
sys.exit(0)
The factory, setup, and library code is nothing unusual but I can post
it if you need to see it.
More information about the Twisted-Python
mailing list