Giter VIP home page Giter VIP logo

revolver's Introduction

Build Status Code Climate

revolver

revolver

revolver is a round-robin load balancer for Erlang processes.

Compared to poolboy (https://github.com/devinus/poolboy) or worker_pool (https://github.com/inaka/worker_pool), revolver is very simple and small (~150 LOC) with no concept of a lease and no assumptions about the workers.

The idea is that you have an existing OTP supervisor with children (your pool) and to balance accross those. This design makes it perfect for the fast paralellization of many equally sized tasks.

In addition, revolver has the notion of beeing disconnected. So when parts of your application are temporarily unavailable (think database connections), revolver acts as a fuse and lets the unaffected parts run while trying to reconnect.

palma

If you are looking for an application to dynamically create pools for balancing with revolver, check out palma.

building revolver

git clone git://github.com/odo/revolver.git
cd revolver
./rebar get-deps compile

performance

On modern hardware, revolver can hand out more than 100 000 pids per second. So it will add an overhead < 10 microseconds to each call.

usage

balancing

The idea is to balance accross processes owned by a supervisor. In this example we use the sasl supervisor (sasl_sup) which has two sub-processes. In a typical setting, you would balance across a large set of identical gen_server processes.

1> application:start(sasl).
ok
2> revolver:balance(sasl_sup, sasl_pool).
{ok,<0.43.0>}
3> revolver:pid(sasl_pool).
<0.40.0>
4> revolver:pid(sasl_pool).
<0.37.0>
5> revolver:pid(sasl_pool).
<0.40.0>
6> revolver:pid(sasl_pool).
<0.37.0>

options

you can start revolver with additional options:

Options = #{
	min_alive_ratio          => 0.75,
	reconnect_delay          => 1000,
	max_message_queue_length => 10,
	connect_at_start         => false
}
revolver:balance(sasl_sup, sasl_pool, Options).

min_alive_ratio: If this portion of the workers are dead, a reload is triggered (default 1.0) reconnect_delay: when disconnected, the wait time between connection attempts (default 1000 ms) max_message_queue_length: maximum number of messages allowed in the inbox of each worker before revolver:pid/1 returns {error, overload} (default undefined) connect_at_start: if you set up the workers after starting revolver, you can set this to false and then connect manually (default true)

refreshing the pool

Members of the pool may die and revolver will notice and take them out of rotation. Eventually it will need to ask the supervisor again for its children. When this happens is specified by the ratio of workers you need to have active. The default is 1.0 (all of them) but if you have many workers and expect them to die frequently you might want to specify a smaller ratio:

revolver:balance(sasl_sup, sasl_pool2, #{ min_alive_ratio => 0.75 }).

calling all members

You can do a series of calls to all members of a pool inside revolver:

1> application:start(sasl).
ok
2> revolver:balance(sasl_sup, sasl_pool).
{ok,<0.43.0>}
3> revolver:map(sasl_pool, fun(Pid) -> proplists:get_value(status, process_info(Pid)) end).
[waiting,waiting]

disconnect and reconnect

If the pool disappears (the supervisor exits or has no children) revolver returns {error, disconnected} when asked for a pid and tries to refresh the pool periodically in the background. The delay for the refresh can be specified at start.

1>  application:start(sasl).
ok

2>  revolver:balance(sasl_sup, sasl_pool, 1.0, 10000).
{ok,<0.44.0>}
=INFO REPORT==== 2-Oct-2014::09:55:41 ===
revolver: Found 2 new processes of 2 total for sasl_sup, connected.

3> revolver:pid(sasl_pool).
<0.38.0>

Everything fine so far. Now we stop sasl (the pool):

4>  application:stop(sasl).
ok

=INFO REPORT==== 2-Oct-2014::09:55:53 ===
    application: sasl
    exited: stopped
    type: temporary

=INFO REPORT==== 2-Oct-2014::09:55:53 ===
revolver: The process <0.41.0> (child of sasl_sup) died.

=ERROR REPORT==== 2-Oct-2014::09:55:53 ===
revolver: Reloading children from supervisor sasl_sup.

=ERROR REPORT==== 2-Oct-2014::09:55:53 ===
revolver_utils: Supervisor sasl_sup not running, disconnected.

=ERROR REPORT==== 2-Oct-2014::09:55:53 ===
revolver trying to reconnect in 10000 ms.

5>  revolver:pid(sasl_pool).
{error,disconnected}

So revolver is disconnected and says so if you ask for a pid. As soon as the pool is there again, revolver reconnects.

6>  application:start(sasl).
ok
=INFO REPORT==== 2-Oct-2014::09:56:13 ===
revolver: Found 2 new processes of 2 total for sasl_sup, connected.

7>  revolver:pid(sasl_pool).
<0.58.0>

If at some point you like revolver to pick up new processes in the pool you can tell it specifically to connect/rescan:

8> revolver:connect(sasl_pool).
ok
=INFO REPORT==== 6-Nov-2014::09:21:29 ===
revolver: Found 0 new processes of 2 total for sasl_sup, connected.

integrating into applications

In order to integrate into a supervision tree you can get the child spec from revolver_sup:

1> ChildSpec = revolver_sup:child_spec(target_supervisor, pool_name, 1.0, 1000).
{pool_name_revolver_sub,{revolver_sup,start_link,
                                      [target_supervisor,pool_name,1.0,1000]},
                        permanent,1000,supervisor,
                        [revolver_sup,revolver]}
2> supervisor:start_child(existing_supervisor, ChildSpec).

tests

./rebar eunit skip_deps=true

revolver's People

Contributors

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