# HG changeset patch # User Tero Marttila # Date 1266700003 -7200 # Node ID 8574aeff9b367350318182956d0bee7cd0972343 # Parent a849c00b63f898701ecd51cb2d1295857fde0513 blind error handling tweaks diff -r a849c00b63f8 -r 8574aeff9b36 fixbot/api/amp.py --- 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() + diff -r a849c00b63f8 -r 8574aeff9b36 fixbot/irc.py --- 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 diff -r a849c00b63f8 -r 8574aeff9b36 fixbot/logwatch/sources.py --- 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, ) diff -r a849c00b63f8 -r 8574aeff9b36 fixbot/module.py --- 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 "" % (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()