Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing a Facebook BigPipe System in Pyramid

Recently, I read an article by Facebook about their new page pipelining system. Currently, there are several Github projects with similar implementations, but they are all written in Php.

What is BigPipe?

BigPipe is a system that Facebook has come up with that makes it seem that pages load faster. A single page is divided into small pagelets, so it looks like this, where each box is a pagelet: enter image description here

So the logic of loading a whole web page turns into:

  1. First request to Server from client, skeleton html generated very fast, has bigpipe javascript.
  2. When client receives skeleton HTML, it runs the BigPipe javascript.
  3. While the connection to server remains persistent, "pagelets" are flushed down the pipe to the client and rendered by the bigpipe javascript.
  4. HTML, CSS, and JS for each pagelet is downloaded and rendered when it is received, so each pagelet is loaded separately, giving a sensation of faster loading.

Their data shows around a 2x page load time improvement.

The Problem

The main problem with implementing this in Pyramid is that I have not found a way to keep a persistent HTTP connection with the client to be able to flush these "pagelets" down the pipe. I've experimented with response.app_iter, but the generator yields are not be flushed, rather the whole response is being generated first, then flushed all at once down the pipe. Is there a way to flush multiple "responses" down a persistent connection with Pyramid?

like image 756
Wiz Avatar asked Jun 13 '13 02:06

Wiz


1 Answers

From here: https://webob.readthedocs.org/en/latest/differences.html?highlight=stream

This can make CherryPy stream the response body out directory. There is direct no equivalent; you can use a dynamically generated iterator to do something similar.

Pyramid uses the webob library to model requests and responses, from the documentation of which the above quotation is taken. Accordingly, I would say there is no way to do this with "Standard" Pyramid/Pylons.

Instead, you are going to have to use a different library to process responses (and maybe requests). This may give you some ideas on how to do that: http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/designdefense.html

Alternatively, you might try subclassing the response object to add that functionality, possibly by delegating to code from another library which does support that.

You should probably select a library which does support this, and ask on the Pyramid mailing list how best to hook that in.

like image 153
Marcin Avatar answered Oct 17 '22 18:10

Marcin