Building a rudimentary cache in Python using Twisted
Every now and then I try and see if I can take something that I built in Java and build it in Python. After having thought of doing a socket application in Python using the Twisted framework, something other than the basic echo. Finally I did it today, by building a simple rudimentary cache with just PUT and GET commands, not even a delete. I admit it is lazy of me, but this illustrates the simplicity and this can be easily built on top of.
So what do you need? You need Python, I used version 2.7, and the Twisted framework - http://twistedmatrix.com/trac/.
Once you have these two - read on.
Basics of twisted - protocol
When you start writing sockets in Twisted, you need to have a protocol that will handle the data that comes from the client. Twisted provides implementations of the most popular protocols, and you can build on top of these or using the base protocol class. Once you have a protocol, it is recommended that you build a protocol factory that can be used to instantiate the protocol. This also is very simple. All this can be achieved in very very few lines of code - I found that if I used something like Netty or Mina in Java, then I would write far more lines of code to get this done and doing it in Python is a breeze. The screenshot below shows all the code required to create the basic cache protocol that I built. More on why I built it using a dict, but this is pretty much it.
Starting a server using this protocol
There are many ways to start a server in Twisted, you can use a reactor to start a simple server that does not get daemonized, or you can use the twistd command to start a server using what is called the Application object - by doing so Twisted will take care of starting the server, logging and also running it as a daemon. In order to do this though you need to write a .tac file which is just another python script. This is how it looks -
Once you have this, you can start the server using the command ‘twistd -noy server.tac’ and it will start up the server waiting for the requests.
A few words about the cache before we go to the client
As you can see the cache itself is a very trivial implementation with just a put and get functionality, and does not do any checking etc. This is just to illustrate the Twisted framework, and you can easily add more functionality. The cache uses a global dict to store the values - since keys in a dict are unique, this will ensure that we have only one value in the cache. Also dict has a lookup time of O(1) for any number of dict entries - this means that even when the cache has a million records, it will retrieve the results equally fast.
And now the client before we debate if this code has any real life use in the current state
The below two screenshots which are pretty self explanatory show how we can write client code and how we can use the server. It also shows the server logs with cache values.
This is very very very rudimentary code and does not have any application in any large enterprise system where there is need for reliability security etc. It cannot be used without heavy changes to add a lot of missing functionality. That said the code is not useless - it can be used to learn and also in small applications or testing where someone wants to mock a cache or whip up a simple cache on is own, this can be used to do some ground work.