[Twisted-web] integrating inotify into a protocol

Phil Mayers p.mayers at imperial.ac.uk
Wed Mar 30 05:49:15 EDT 2011


On 03/30/2011 02:21 AM, Jason Pepas wrote:

> another way to say this is that the protocol/client/factory side of
> things is all object-oriented, but the inotify side of things is just
> procedural.  n'ere the twain shall meet?
>
> specifically, the notifier expects the callback to accept 3 args:
> _Watch object, path, and mask.  so, when you try to pass in a class
> method as one of its callbacks, you get something like this:
>
>    exceptions.TypeError: unbound method announceNewFile() must be
> called with Echo instance as first argument (got _Watch instance
> instead)

Well, sure. You need to pass in an *instance* method, not a class method 
i.e. only once your Echo protocol class has been instantiated, do:

class Echo(LineReceiver):
   def connectionMade(self):
     inotify.whatever(self.announceNewFile, path, mask)

But if you want >1 client, you'll probably want something a bit more 
sophisticated. Specifically, you'll probably want to route the inotify 
callbacks via an instance method on the Factory, then have the Factory 
maintain a list of all Protocol instances, and fan out the inotify to 
all the clients.

e.g.

class Echo(...):
   def connectionMade(self):
     self.factory.clients.append(self)
   def connectionLost(self, ...):
     if self in self.factory.clients:
       self.factory.clients.remove(self)
   def announceNewFile(self, ...):
     whatever

class Factory(...):
   protocol = Echo

   def __init__(self):
     self.clients = []

   def announceNewFile(self, *p, **kw):
     for client in self.clients:
       client.announceNewFile(*p, **kw)


def main():
   f = Factory()
   inotify.whatever(f.announceNewFile, path, mask)
   reactor.listenTCP(port, f)
   reactor.run()



More information about the Twisted-web mailing list