Running Tornado application inside PyPy
The title says it all, this blog post will demonstrate on how to run Tornado application inside PyPy environment.
Prerequisites:
- The OS we’ll use is OS X Snow Leopard.
- system-wide pip.
- Obviously, default python installation (2.6.1).
Virtualenv with PyPy in a nutshell:
- Install virtualenv
sudo pip install virtualenv
- Download your binary of choice from http://pypy.org/download.html
- Extract the compressed file to a location, for example: /tmp. You will see directory that look like this: pypy-c-jit-43780-b590cf6de419-osx64
- Go to the desired location of your pypy environment, for example: ~/www
cd ~/www
- Create a new virtualenv, let’s call it pypy-env. It is best to not include site-packages because we don’t really know if pypy has support on your existing eggs.
virtualenv —no-site-packages -p /tmp/pypy-c-jit-43780-b590cf6de419-osx64/bin/pypy pypy-env
- Activate your virtualenv
source ~/www/pypy-env/bin/activate
- Start installing eggs. All your eggs will be located inside ~/www/pypy-env/site-packages
pip install MySQLdb-python
pip install tornado
Something a little different (my own approach):
In this section, I will suggest my style of setting up pypy environment for each Tornado app. It is heavily influenced by Isolate in Ruby land. If you don’t like what you read here, that’s cool. Just follow the nutshell above.
I like how Isolate puts all ruby gems under $RAILS_ROOT/tmp/isolate. It makes auditing dependencies easy. So, we’ll emulate that by putting pypy-env inside our application directory (Example: ~/www/my-tornado-app/pypy-env). You can automate the whole process by using this bash script.
Don’t forget to exclude the pypy-env and pypy binary directories on your source control (.gitignore or .hgignore).
Stumbling blocks:
- Unfortunately, not everything is rosy. MySQLdb-python still doesn’t work quite right in Tornado in PyPy (See: stacktrace). It seems like copy.deepcopy doesn’t like something inside MySQLdb.converters.conversions. To side-step this problem, I added support for pymysql inside tornado.database (See: this commit). Once you apply this patch, simply do: pip install pymysql
- Another stumbling block is intermittent SSL error when using tornado.auth library. It is already documented and fixed by other people. Since the fix is recent(2011-05-15), you need to compile PyPy from source to get it. The error was this:
AttributeError: ‘SSLObject’ object has no attribute ‘peer_certificate’
Conclusion:
Besides those two issues, Tornado runs like a champ inside PyPy. Unsurprisingly, the app use a lot more RAM when running inside PyPy (without: 15mb vs with: 45mb).