Search code examples
pythondjangononblockingthriftthrift-protocol

Non-blocking Thrift-Server with Django


I need to access data coming from a Django webapp via a Thrift interface. I'd like to do this in a non-blocking way (eg. using libevent/gevent...) but there aren't many example implementations (in python) around, so I'd like ask here for any examples/hints/experiences!

Please note that this question is about using Thrift, not any other protocol, and I know that there might be better frameworks for this purpose than Django, but using it is also a requirement!


Solution

  • This can be done by implementing a thrift server within a Django admin command. See the link for the file structure you will need. In the command file, which you may call "thrift_server.py", you would then implement the usual thrift server as follows:

    import sys
    from django.core.management.base import BaseCommand
    
    from thrift.transport import TSocket
    from thrift.transport import TTransport
    from thrift.protocol import TBinaryProtocol
    from thrift.server import TServer
    
    #import thrift files here
    
    #now define the service handler according to your thrift method declaration
    class ServiceHandler:
        def __init__(self):
            pass
            #self.log = {}
        def thriftMethodName(self, arg):
            print "hello world!"
            #here you have access to anything in the django framework
            return True
    
    class Command(BaseCommand):
        def handle(self, *args, **kwargs):
            handler = ServiceHandler()
            processor = SaleService.Processor(handler)
            transport = TSocket.TServerSocket(port=9090)
            tfactory = TTransport.TBufferedTransportFactory()
            pfactory = TBinaryProtocol.TBinaryProtocolFactory()
    
            server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
    
            # You could do one of these for a multithreaded server
            #server = TServer.TThreadedServer(processor, transport, tfactory, pfactory)
            #server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)
    
            self.stdout.write('Starting thrift server...')
            server.serve()
            self.stdout.write('done.')
    

    Notice that multithreaded server options are described above, though I have not tested these yet.

    You could then run the daemon as follows:

    (virtualenv) /django_project/ > python manage.py thrift_server