from twisted.protocols import amp
from twisted.python import log
from fixbot.module import ModuleInfo, Event
class CmdModuleRegister (amp.Command) :
"""
Register module
"""
arguments = [
('name', amp.String()),
]
class CmdModuleEvent (amp.Command) :
"""
Broadcast event
"""
arguments = [
('type', amp.String()),
('msg', amp.String()),
]
class CmdModuleAbort (amp.Command) :
"""
Module has failed and will now disconnect
"""
arguments = [
('msg', amp.String()) # string describing the error occuring
]
requiresAnswer = False
class ServerProtocol (amp.AMP) :
"""
Nexus-side command handler
"""
# the registered ModuleInfo
module = None
def connectionMade (self) :
log.msg("Module connecting from: %s" % (self.transport.getPeer()))
def connectionLost (self, reason) :
log.err(reason, "Module lost")
if self.module :
# drop it
self.factory.nexus.unregisterModule(self.module, reason.getErrorMessage())
@CmdModuleRegister.responder
def on_ModuleRegister (self, name) :
# construct the ModuleInfo
mi = ModuleInfo()
mi.name = name
log.msg("Module registered: %s" % (mi))
# register
self.factory.nexus.registerModule(mi, self)
self.module = mi
# ok
return {}
@CmdModuleEvent.responder
def on_ModuleEvent (self, type, msg) :
# as Event
e = Event(self.module, type, msg)
# publish
self.factory.nexus.handleEvent(e)
# ok
return {}
@CmdModuleAbort.responder
def on_ModuleAbort (self, msg) :
# unhook
module = self.module
self.module = None
# report
self.factory.nexus.unregisterModule(self.module, msg)
# XXX: stop accepting commands etc?
class ClientProtocol (amp.AMP) :
"""
Module-side command sender/handler
"""
def connectionMade (self) :
"""
Connected to nexus, send ModuleRegister
"""
# register
self.sendModuleRegister(self.factory.name).addCallback(self._ModuleRegisterOK)
def connectionLost (self, reason) :
"""
Disconnected from nexus, for whatever reason...
"""
log.err(reason, "API connection lost")
# XXX: was this expected? Reconnect?
def sendModuleRegister (self, name) :
"""
Register with given module name
"""
return self.callRemote(CmdModuleRegister, name=name)
def _ModuleRegisterOK (self, ret) :
"""
Registered with nexus, commence operation
"""
self.factory._onRegistered(self)
def sendEvent (self, event) :
"""
Broadcast event to nexus
"""
self.callRemote(CmdModuleEvent, type=event.type, msg=event.msg)
def sendModuleAbort (self, msg) :
"""
Send CmdModuleAbort - no response is expected
"""
self.callRemote(CmdModuleAbort, msg=msg)
def abort (self, msg) :
"""
Send abort message and drop connection
"""
# disconnect. This should leave the transport to flush buffers, and then call connectionLost
# should also stop us from sending any more commands
self.transport.loseConnection()