Giter Site home page Giter Site logo

django-c10k-demo's Introduction

README

django-c10k-demo handles 10 000 concurrent real-time connections to Django.

This demo combines several interesting concepts: the C10k problem, the WebSocket protocol, the Django web framework, and Python's upcoming asynchronous IO support.

Running the demo

  • Install Python 3.3, the Tulip library, and Django 1.5.
  • Clone this repository.
  • Configure your OS to allow lots of file descriptors. On OS X: sudo sysctl -w kern.maxfiles=40960 kern.maxfilesperproc=20480
  • Open two shells and bump their file descriptor limit: ulimit -n 10240
  • In the first shell, start the server: python manage.py runserver
  • In the second shell, start the clients: python manage.py testecho

If you're lucky, the server won't display anything, and the client will show the number of connections, peaking at 10000 clients are connected!. The demo takes five minutes if your system is fast enough.

The connections are established over a period of two minutes. Once connected, each client repeats the following sequence three times: wait one minute, send a message, and read the reply of the server. Clients also receive a welcome and a goodbye message from the server.

If you don't reach 10 000 connections, it means that some clients finish their sequence and disconnect before all the clients are connected, because your system is too slow. If you see exceptions, it means that your OS isn't tuned correctly for such benchmarks. Decreasing CLIENTS or increasing DELAY in testecho may help in both cases.

Under the hood

Here are the underlying components in no particular order, with some hints on their quality and reusability.

WebSocket implementation

django-c10k-demo provides a server-side implementation of the WebSocket protocol compatible with Tulip.

The WebSocket class provides three methods:

  • read_message() is a coroutine that returns the content of the next message asynchronously;
  • write_message(data, opcode=None) writes the next message — Tulip ensures this doesn't block;
  • close() closes the connection.

The code is in c10ktools.websockets.

WSGI server running on top of Tulip

django-c10k-demo adapts Django's built-in developement server to run on top of Tulip. This involves some inelegant plumbing to resolve the impedance mismatch between WSGI and tulip.http.

The code is merely functional. There's little point in optimizing it: either the standard library will eventually provide an asynchronous WSGI server, or the future of asynchronous apps won't involve WSGI.

This component can be used independently by adding the 'c10ktools' application to INSTALLED_APPS. This overrides the django-admin.py runserver command to run on Tulip. Auto-reload works.

The implementation is in c10ktools.servers.tulip. A test page is available at http://localhost:8000/test/wsgi/.

Hook for the upgrade to WebSocket

The design of WSGI predates real-time on the web and PEP 3156 doesn't propose to update it. Hopefully his point will be addressed by a future version of the standard (PEP 3356 anyone?). In the meantime our only choice is to bastardize it, steering away from WSGI compliance — sorry Graham.

The WebSocket handler needs to grab the read and write streams for further communications. A straightforward solution is to add them in environ, like httpclient does.

More importantly, it needs to hook on the WSGI request processing. Since it's a coroutine, it can only be called from another coroutine. I chose to call it in close() to allow completing the handshake cleanly within WSGI. (Still, the handshake isn't compliant because the reply contains a hop-by-hop header.)

These features are also implemented in c10ktools.servers.tulip.

Once again, there's little point in optimizing them until the future of WSGI and asynchronous servers is clarified.

WebSocket API for Django

Here's an example of a WebSocket handler in Django:

from c10ktools.http import websocket

@websocket
def handler(ws):
    # ws is a WebSocket instance. Let's echo the messages we receive.
    while True:
        ws.write_message((yield from ws.read_message()))

WebSocket handlers are hooked in the URLconf like regular HTTP views. Arguments can be captured in the URLconf and passed to the handlers.

This doesn't allow sharing an URL between a regular HTTP view and a WebSocket handler, but I'm happy with this limitation as it's probably a good practice to keep them separate anyway.

Inside a WebSocket handler, you can use yield from ws.read_message() and ws.write_message() freely. You can also call ws.write_message() from outside the handler.

The @websocket decorator takes care of marking the handler as a @tulip.coroutine. ws.close() is called automatically when the handler returns.

The implementation is in c10ktools.http.websockets. A test page is available at http://localhost:8000/test/.

Testing script

There isn't much to say about this code. It's located in c10ktools.clients.tulip and c10ktools.management.commands.testecho.

django-c10k-demo's People

Contributors

aaugustin avatar ptone avatar

Watchers

Jeremy Bowers avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.