-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BSD 2-clause for double-boiler and MIT carried over from Foreman. Signed-off-by: Dan Farina <drfarina@acm.org>
- Loading branch information
Dan Farina
committed
Oct 4, 2011
1 parent
13c7bb2
commit b8177e8
Showing
3 changed files
with
128 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
Copyright (c) 2011, Daniel Farina | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted provided that the following conditions are met: | ||
* Redistributions of source code must retain the above copyright | ||
notice, this list of conditions and the following disclaimer. | ||
* Redistributions in binary form must reproduce the above copyright | ||
notice, this list of conditions and the following disclaimer in the | ||
documentation and/or other materials provided with the distribution. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY | ||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
(The copyright years and holders are not explicitly filled out in the | ||
Foreman projct, but they do say "MIT", so here's a copy of the license | ||
text that follows) | ||
|
||
Copyright (c) <year> <copyright holders> | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
Double-Boiler | ||
============= | ||
|
||
Double Boiler is a work-in-progress demonstration of how to pack extra | ||
processes into every Heroku (or other Heroku-alike) process, as well | ||
as attempting to squeeze as much throughput as possible out of a | ||
single Heroku process. | ||
|
||
It currently uses Python, Django, Celery, and Foreman, a desktop | ||
implementation of the Procfile format that is preferred by Heroku. | ||
Because there is a second Procfile *not* interpreted by Heroku | ||
(``LocalProcfile``) that is used to start more processes within a | ||
single Heroku process (seen in ``Procfile``) there is a | ||
double-layering of Procfiles. It is this technique that gives the | ||
project its name. | ||
|
||
The intention was that hobbyists who wanted some asynchronous | ||
execution via Celery who cannot justify two full Heroku processes | ||
could still get all the expressivity they desire, so long as all their | ||
required processes fit into one of the containers furnished by their | ||
platform-as-a-service provider. In a system large enough to keep | ||
multiple process types busy this trick is probably just extra | ||
complexity. | ||
|
||
Finally, each of the processes started in ``LocalProcfile`` are | ||
themselves multi-process: Celery starts multiple forked workers to | ||
service asynchronous jobs, and Gunicorn starts multiple web serving | ||
backends. To get even more throughput from each forked Gunicorn | ||
worker, the gevent backend is used to process multiple requests per | ||
Gunicorn backend in a cooperatively interleaved fashion, using the | ||
time that would normally be spent waiting for I/O to do even more | ||
work. | ||
|
||
The history of the project in Git attempts to be reasonably well | ||
documented, but there is no reason why it cannot be used as a | ||
hello-world template in its latest revision. | ||
|
||
Caveats | ||
------- | ||
|
||
* Because this project intended to be a template of kinds, no stable | ||
Django ``SECRET_KEY`` (in ``settings.py``) is defined. Instead, a | ||
random one is created upon every startup. It is completely | ||
necessary to make a stable ``SECRET_KEY`` in production settings, | ||
and the current code reads an environment variable called | ||
``DJANGO_SECRET_KEY``. | ||
|
||
One can set it in their Heroku environment easily:: | ||
|
||
$ heroku config:add DJANGO_SECRET_KEY='my-long-random-thing-here' | ||
|
||
* Also, as a normal Django project, it is necessary to run ``syncdb`` | ||
to have things run at all correctly, especially the first time. You | ||
can do this on Heroku with:: | ||
|
||
$ heroku run hellodjango/manage.py syncdb | ||
|
||
* There has been no attempt to try tweaking the concurrency (aka | ||
number of forked workers) levels of Celery and Gunicorn to be | ||
sensible for Heroku. If you see out of memory errors (Python calls | ||
these MemoryError exceptions) then some of your workers or web | ||
processes may be using too much memory, and reducing the number of | ||
forked workers may help. | ||
|
||
* gevent monkey-patches underlying Python libraries to make I/O done | ||
through them also imply a cooperative-scheduling task-switching | ||
opportunity. This very often but does not always work (bugs or | ||
misbehavior between gevent and other common packages are tracked | ||
with the gevent project and mailing lists). One can opt-out of | ||
gevent by using the 'sync' backend (as detailed by the Gunicorn | ||
documentation) instead of the gevent one. | ||
|
||
* Foreman is a tool written in Ruby with a standalone tarball that | ||
only requires the interpreter itself. Unfortunately I found a bug | ||
in the standalone package, so I had to patch it. The modified | ||
source is included in the vendor/foreman directory. Vendoring the | ||
full project feels a bit excessive, but as long as one must use a | ||
Procfile to use Heroku, one may as well write two Procfiles, rather | ||
than a Procfile and a shell script. | ||
|
||
The bug is reported, and when foreman is re-freshed to a new version | ||
no patches will likely be necessary. | ||
|
||
TODO | ||
---- | ||
|
||
The current and (currently) very unexciting demonstration of this can | ||
be seen at http://double-boiler.heroku.com. It just shows a hello | ||
world Django page; it is indiscernible from a normal Django "hello | ||
world". | ||
|
||
I'd like to have a more compelling demo than hello world (say, | ||
generating jobs rapidly via many, many ajax calls and then serving | ||
them) to show gevent, Gunicorn, and Celery in action. A mini | ||
benchmark would be nice. I would like contributions in this area, | ||
because I'm not really a great nor enthusiastic web developer. |