A scalable, extensible, distributed messaging system.
Built for speed, Hurricane can send and receive as many as the network can handle. Hurricane is so fast that it can do an entire process-to-process round-trip in 60 microseconds.
Clustering is provided out of the box with the distribution manager. Even in huge clusters, each node only needs to be configure to talk to one other node—the rest is magic.
Hurricane ships first-class support for the powerful Scatter-Gather pattern of service communication. Give each message a unique tag and the responses are guaranteed to arrive in-order.
Hurricane acts as your concurrency framework. With Scatter-Gather support, easily distribute work over any number of processes. Suddenly, parallelism is easy and bug-free.
Really any WSGI or Rack enabled framework. Drivers and handlers are provided so that your Favorite Python or Ruby Framework can be hooked up to Hurricane to serve HTTP requests.
The Hurricane project current ships drivers for Ruby, Python, PHP, and Java. Interested in support for your language? Please contribute—your help makes a difference!
Out of the box, messaging works over TCP and over Standard I/O. With Standard I/O-based messaging, Hurricane will manage and restart broken processes automatically.
At startup, Hurricane loads and compiles each piece of itself. Any number of "after-factory" modules can be added simply by configuring a path for each custom module.
Hurricane is created, developed, and shared with the world under the New BSD License. Go ahead and do something great with it, and while you're at it, please contribute—your help makes Hurricane better.
For Hurricane itself, Erlang R14B01+ is recommended. To get additional HTTP features, grab a copy of MochiWeb.
# First set everything up $ curl 'https://nodeload.github.com/hurricane/hurricane/zipball/master' > hurricane.zip $ unzip hurricane.zip $ mv hurricane-hurricane* hurricane $ cd hurricane $ make $ curl 'https://nodeload.github.com/mochi/mochiweb/zipball/master' > mochiweb.zip $ unzip mochiweb.zip $ mv mochi-mochiweb* mochiweb $ cd mochiweb $ make $ cd .. $ ./run.escript examples/basic.config # Now you're ready to run the demos in the examples for one of the language drivers
The Ruby driver is compatible with Ruby 1.8.6+. Included is the Erlang Codec, Hurricane Gateway Tools, and Rack Handler.
require 'hurricane' gateway = Hurricane::Gateway.new(Erlang::SocketWrapper.new('localhost', 3000)) loop do request = Hurricane::Message.new() request.type = 'request' request.destination = 'time_server' request.tag = 0 request.data = nil gateway.do_send(request) p gateway.do_recv() end
Run your favorite Rack-enabled Ruby framework:
rackup --server Hurricane
The Python driver is compatible with Python 2.4+. Included is the Erlang Codec, Hurricane Gateway Tools, and WSGI Server.
from hurricane import Gateway, Message from hurricane.erl_codec import SocketWrapper gateway = Gateway(SocketWrapper('localhost', 3000)) while True: message = Message() message.type = 'request' message.destination = 'time_server' message.tag = 0 message.data = None gateway.send(message) print gateway.recv()
Run your favorite WSGI-enabled Python framework:
Create myapp.py:
import os import sys sys.path.append('/path/to/django/project') os.environ['DJANGO_SETTINGS_MODULE'] = 'mydjangoproject.settings' from django.core.handlers.wsgi import WSGIHandler application = WSGIHandler()
and then run:
hurricane_wsgi_server --app myapp
The PHP driver is compatible with PHP 5.3+. Included is the Erlang Codec and Hurricane Gateway Tools.
PHP is a platform that sees significant performance improvements when using Hurricane, due to the ability to have long-running processes.
<?php require 'hurricane.php'; $gateway = new \Hurricane\Gateway(new \Erlang\SocketWrapper('localhost', '3000')); while (true) { $request = \Hurricane\Message::create() ->setType('request') ->setDestination('time_server') ->setTag(0) ->setData(null); $gateway->send($request); $response = $gateway->recv(); echo $response->getData() . PHP_EOL; }
The Java driver is written and tested using the OpenJDK. Included is the Erlang Codec and Hurricane Gateway Tools.
import org.hurricane.Gateway; import org.hurricane.Message; public class TcpExample { public static void main(String[] args) throws Exception { Gateway gateway = new Gateway("localhost", 3000); while (true) { Message request = new Message(); request.setType("request"); request.setDestination("time_server"); request.setTag(0); request.setData(""); System.out.println(request); gateway.send(request); System.out.println(gateway.recv()); } } }
Here is a configuration example. It is usually the minimum amount of configuration needed to make Hurricane boot.
The compile_modules
section lists all of the Erlang files to compile and load into Hurricane. To add custom modules to Hurricane, simply drop in the path to the module here.
The add_code_paths
section lists all of the additional paths where Hurricane will search for code. For example, to enable HTTP support, the path to the compiled MochiWeb files is given.
The log_level
section specifies the log level. The standard log levels are supported: emergency
, alert
, critical
, error
, warning
, notice
, info
, debug
The start_modules
section configures which modules to start with which options. Each module must have a start/1
function that gets called with the given args.
{ load_modules, [ "ebin/hurricane", "ebin/hurricane_config_server", "ebin/hurricane_utils", "ebin/hurricane_stdio_server", "ebin/hurricane_tcp_server", "ebin/hurricane_http_server", "ebin/hurricane_log_server", "ebin/hurricane_supervisor", "ebin/hurricane_message_delegate", "ebin/hurricane_distribution_manager" ] }. { add_code_paths, [ "mochiweb/ebin" ] }. {log_level, info}. { start_modules, [ [ {module, hurricane_tcp_server}, {args, [{listen_port, 3000}]} ] ] }.
This is an example configuration fragment for the Hurricane TCP Server. Multiple of these can be started, but never on the same port.
The only option that this module currently takes is listen_port
, which configures which port this instance of the TCP Server will listen on for incoming connections.
[ {module, hurricane_tcp_server}, {args, [{listen_port, 3000}]} ]
This is an example configuration fragment for the Hurricane STDIO Server.
The cmd
option specifies which command to run to create a process that will be able to do messaging over Standard I/O.
The group_name
option which message group the process(es) will belong to.
The port_timeout
option specifies after how many milliseconds the process should be considered hung and restarted (when waiting for a reply). This is OPTIONAL (default: 10000)
The port_startup_timeout
option specifies after how many milliseconds the process should be considered hung and restarted (when starting the process and waiting for the initial ready payload). This is OPTIONAL (default: 10000)
This module also shows Hurricane's ability to start many instances of a module. The count
top-level module config specifies how many instances of a module to start. Usually, the default setting of 1 is fine, but with the STDIO server, it is how many copies of a message handler are run.
[ {module, hurricane_stdio_server}, { args, [ {cmd, "/usr/bin/python examples/http_handler.py"}, {group_name, http_handler}, {port_timeout, 10000}, {port_startup_timeout, 1000} ] }, {count, 2} ]
This is an example configuration fragment for the Hurricane HTTP Server. Note that MochiWeb must be in the code load path.
The listen_port
option configures which port this instance of the HTTP Server will listen on for incoming connections.
The server_name
option configures the name of the HTTP Server (for use with handler applications). This is OPTIONAL (default: "localhost")
The handler_group
option configures which process group will be used to handle HTTP requests. This is OPTIONAL (default: http_handler)
The response_timeout
option specifies how many milliseconds to wait until considering a request to have timed out. This is OPTIONAL (default: 10000)
The static_dir
option specifies which directory to serve static files out of. This is OPTIONAL (default: undefined)
[ {module, hurricane_http_server}, { args, [ {name, some_name}, {listen_port, 8000}, {server_name, "localhost"}, {handler_group, http_handler}, {response_timeout, 10000}, {static_dir, "/tmp/"} ] } ]
This module provides full clustering for Hurricane. As long as every node in a cluster "sees" at least another node, the entire cluster will be operational and able to route messages around correctly.
The magic_cookie
option configures the secret magic cookie value that has to match up between all nodes for them to be able to connect to each other.
The node_name
option provides a unique name for this node.
The connect_nodes
option specifies which other nodes to connect to. Note that single-quotes are used to specify the name of the other nodes as Erlang atoms.
[ {module, hurricane_distribution_manager}, { args, [ {magic_cookie, the_magic_cookie}, {node_name, hurricane_node_1}, {connect_nodes, ['a_hurricane_node@a_hostname.local']} ] } ]