Giter VIP home page Giter VIP logo

heroku-forward's Introduction

Heroku::Forward Build Status

Beat Heroku's 60 seconds timeout with a proxy.

What's this?

Heroku will report an application crashing and yield an R10 Boot Timeout error when a web process took longer than 60 seconds to bind to its assigned $PORT. This error is often caused by a process being unable to reach an external resource, such as a database or because Heroku is pretty slow and you have a lot of gems in your Gemfile.

This gem implements a proxy using em-proxy. This proxy is booted almost immediately, binding to the port assigned by Heroku. Heroku now reports the dyno up. The proxy then spawns your application's web server and establishes a connection over a unix domain socket (a file) between the proxy and the application. Once the application is ready, it will be able to serve HTTP requests normally. Until then requests may queue and some may timeout depending on how long it actually takes to start.

Usage

Add heroku-forward and em-proxy to your Gemfile. Curently requires HEAD of em-proxy because of this pull request.

gem "heroku-forward", "~> 0.1"
gem "em-proxy", ">= 0.1.8"

Create an application rackup file, eg. my_app.ru that boots your application. Under Rails, this is the file that calls run.

require ::File.expand_path('../config/environment',  __FILE__)
run MyApp::Application

Modify your rackup file as follows. Under Rails this file is called config.ru.

require 'rubygems'
require 'bundler'

$stdout.sync = true
Bundler.require(:rack)

port = (ARGV.first || ENV['PORT'] || 3000).to_i
env = ENV['RACK_ENV'] || 'development'

require 'em-proxy'
require 'logger'
require 'heroku-forward'

application = File.expand_path('../my_app.ru', __FILE__)
backend = Heroku::Forward::Backends::Thin.new(application: application, env: env)
proxy = Heroku::Forward::Proxy::Server.new(backend, { host: '0.0.0.0', port: port })
proxy.logger = Logger.new(STDOUT)
proxy.forward!

This sets up a proxy on the port requested by Heroku and runs your application with Thin.

Foreman

Heroku Cedar expects a Procfile that defines your application processes.

web: bundle exec ruby config.ru
worker: bundle exec rake jobs:work

You can use foreman to test the proxy locally with foreman start web.

Heroku Log

Here's the log output from an application that uses this gem. Notice that Heroku reports the state of web.1 up after just 4 seconds, while the application takes 67 seconds to boot.

2012-12-11T23:33:42+00:00 heroku[web.1]: Starting process with command `bundle exec ruby config.ru`
2012-12-11T23:33:46+00:00 app[web.1]:  INFO -- : Launching Backend ...
2012-12-11T23:33:46+00:00 app[web.1]:  INFO -- : Launching Proxy Server at 0.0.0.0:42017 ...
2012-12-11T23:33:46+00:00 app[web.1]: DEBUG -- : Attempting to connect to /tmp/thin20121211-2-1bfazzx.
2012-12-11T23:33:46+00:00 app[web.1]:  WARN -- : no connection, 10 retries left.
2012-12-11T23:33:46+00:00 heroku[web.1]: State changed from starting to up
2012-12-11T23:34:32+00:00 app[web.1]: >> Thin web server (v1.5.0 codename Knife)
2012-12-11T23:34:32+00:00 app[web.1]: >> Maximum connections set to 1024
2012-12-11T23:34:32+00:00 app[web.1]: >> Listening on /tmp/thin20121211-2-1bfazzx, CTRL+C to stop
2012-12-11T23:34:53+00:00 app[web.1]: DEBUG -- : Attempting to connect to /tmp/thin20121211-2-1bfazzx.
2012-12-11T23:34:53+00:00 app[web.1]: DEBUG -- : Proxy Server ready at 0.0.0.0:42017 (67s).

Proxy Forwarding Options

Heroku::Forward::Proxy::Server.forward! accepts the following options:

  • delay: number of seconds to sleep before launching the proxy, eg. proxy.forward!(delay: 15). This prevents queuing of requests or reporting invalid up status to Heroku. It's recommended to set this value to as close as possible to the boot time of your application and less than the Heroku's 60s boot limit.

Fail-Safe

If you're worried about this implementation, consider building a fail-safe. Modify your config.ru to run without a proxy if DISABLE_FORWARD_PROXY is set as demonstrated in this gist. Add DISABLE_FORWARD_PROXY via heroku config:add DISABLE_FORWARD_PROXY=1.

Reading Materials

Contributing

Fork the project. Make your feature addition or bug fix with tests. Send a pull request. Bonus points for topic branches.

Copyright and License

MIT License, see LICENSE for details.

(c) 2012 Daniel Doubrovkine, Art.sy

heroku-forward's People

Contributors

dblock avatar

Watchers

 avatar  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.