--- a/fixbot/api/amp.py Sat Feb 20 22:32:18 2010 +0200
+++ b/fixbot/api/amp.py Sat Feb 20 23:06:43 2010 +0200
@@ -1,4 +1,5 @@
from twisted.protocols import amp
+from twisted.python import log
from fixbot.module import ModuleInfo, Event
@@ -21,6 +22,17 @@
('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
@@ -29,11 +41,25 @@
# 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)
@@ -52,7 +78,17 @@
# 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) :
"""
@@ -68,6 +104,14 @@
# 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) :
"""
@@ -92,4 +136,20 @@
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()
+
--- a/fixbot/irc.py Sat Feb 20 22:32:18 2010 +0200
+++ b/fixbot/irc.py Sat Feb 20 23:06:43 2010 +0200
@@ -3,8 +3,6 @@
from twisted.python import log
import traceback
-import buffer
-
class ReplyException (Exception) :
def __init__ (self, reply) :
self.reply = reply
--- a/fixbot/logwatch/sources.py Sat Feb 20 22:32:18 2010 +0200
+++ b/fixbot/logwatch/sources.py Sat Feb 20 23:06:43 2010 +0200
@@ -37,6 +37,13 @@
log.err(msg)
self.module.error(msg)
+ def connectionLost (self, reason) :
+ """
+ The transport we were connected to has dropped, possibly as a result of our handlers raising an error?
+ """
+
+ self.handleError("lost LogSource for %s: %s" % (self.name, reason.getErrorMessage()))
+
def handleData (self, data) :
"""
Feed binary data into the buffer, processing all lines via handleLine()
@@ -109,6 +116,9 @@
else :
raise ValueError(out)
+ def logPrefix (self) :
+ return "LogSource(%s)" % (self.name, )
+
class File (LogSource, protocol.ProcessProtocol) :
"""
Stream lines from a regular file using /usr/bin/tail -f
@@ -149,11 +159,7 @@
def handleEOF (self) :
self.handleError("!!! EOF on fifo %s, re-opening" % self.name)
- self.reopen()
-
- def connectionLost (self, reason) :
- super(Fifo, self).connectionLost(reason)
- self.handleError("lost fifo for %s: %s" % (self.name, reason.getErrorMessage()))
+ self.reopen()
class UnixDatagramSocket (LogSource, protocol.DatagramProtocol) :
"""
@@ -180,6 +186,4 @@
# handle it as a line of data
self.handleLine(data)
- def logPrefix (self) :
- return "LogSource(%s)" % (self.name, )
--- a/fixbot/module.py Sat Feb 20 22:32:18 2010 +0200
+++ b/fixbot/module.py Sat Feb 20 23:06:43 2010 +0200
@@ -13,7 +13,7 @@
name = None
def __str__ (self) :
- return "Module %s:" % (self.name)
+ return "%s" % (self.name)
def __repr__ (self) :
return "<module %s>" % (self.name, )
@@ -70,6 +70,7 @@
# XXX: legacy: self.secret = config['api-secret']
+
def _onRegistered (self, connection) :
"""
Connected to nexus and registered
@@ -78,16 +79,20 @@
log.msg("Connected and registered")
self.connection = connection
-
+
+ # XXX: abort on errors?
self.handleConnect()
+
+ # XXX: unused, bad interface
def disconnect (self) :
"""
Disconnect from Nexus
"""
self.connection.transport.loseConnection()
-
+
+
def sendEvent (self, type, msg) :
"""
Send event to nexus
@@ -95,6 +100,7 @@
self.connection.sendEvent(Event(self, type, msg))
+
def handleConnect (self) :
"""
Do something once we are connected to nexus and registered
@@ -102,6 +108,13 @@
pass
+ def abort (self, err) :
+ """
+ Abort this module, disconnecting with the given error
+ """
+
+ self.connection.abort(str(err))
+
def makeService (module_class, config, protocol) :
s = service.MultiService()