Telecaster

A multiplexing HTTP proxy based on EventMachine. Forwards every incoming request onto a set of backend servers, collects the responses and sends a summary back to the client.

This is designed to allow independent services to notify each other about changes without tightly coupling them. Each service just calls a Telecaster server, which knows where to forward things to. The publisher gets a summary of which services were called and how they responded, which makes this notification style easier to debug than async message-passing systems.

Telecaster supports delegation, so requests can be distributed to slaves and all the backend responses will be aggregated by the master.

Usage

Create a Telecaster with a list of backend hosts, a logger and a timeout in seconds, then tell it to listen on a port:

require 'telecaster'
require 'logger'

telecaster = Telecaster.new(
  :backends => %w[http://concerts-service http://accounts-service],
  :logger   => Logger.new($stdout),
  :timeout  => 15
)

telecaster.listen(9000)

This boots a Thin server with the request timeout set high enough to accomodate your backend request timeout.

Debugging

If you're developing a backend that will receive forwarded requests from Telecaster, you can temporarily plug it into a running instance using the telex command. Pass in the address of your Telecaster and the address of your development app and Telecaster will begin forwarding requests to it.

In order to support this you need to boot Telecaster on two ports; the second port will use a longer connection timeout to support the socket connections that telex uses.

telecaster.listen(9000, 9001)

To monitor the requests Telecaster is receiving as they arrive, just connect your development application:

$ telex telecaster:9000 localhost:3000

Protocol

On every request, Telecaster returns a 200 response containing a JSON summary of the backend responses, for example:

$ curl localhost:9000/hello
[
  {
    "host": "http://localhost:9001",
    "status": 200,
    "duration": 16,
    "data": {
      "status": "ok"
    }
  },
  {
    "host": "http://localhost:9002",
    "status": 200,
    "duration": 16
  },
  {
    "host": "http://localhost:9003",
    "status": 404,
    "duration": 15
  }
]

This JSON list contains a record for each backend that was called. Each record contains the following fields:

  • host - the hostname of the backend server
  • status - a numetic HTTP status code if a response was received, else nil
  • duration - the request time in milliseconds
  • data - any JSON data returned by the backend

Every backend may return a JSON object using Content-Type: application/json. If it does so, the data is included in the Telecaster summary.

If the backend returns a JSON array, this is interpretted as Telecaster summary data and merged in - this is how Telecaster aggregates responses from delegate servers. So if you want to return custom data, the root of the response must be a single JSON object.

License

(The MIT License)

Copyright (c) 2012-2013 Songkick.com

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.