sbroker

Sojourn Broker - process broker for matchmaking between two groups of processes using sojourn time based active queue management to prevent congestion.

Introduction

sbroker provides a simple interface to match processes. One party calls sbroker:ask/1 and the counterparty sbroker:ask_r/1. If a match is found both return {go, Ref, Pid, RelativeTime, SojournTime}. Ref is the transaction reference. Pid is the other process in the match, which can be changed by using sbroker:ask/2 and sbroker:ask_r/2. SojournTime is the time spent waiting for a match and RelativeTime is the theoretical sojourn time if using the sbroker had no overhead. If no match is found, returns {drop, SojournTime}. The time unit for SojournTime and RelativeTime is set by the time_unit start option to a broker, defaulting to the VM's native unit.

Processes calling sbroker:ask/1 are only matched with a process calling sbroker:ask_r/1 and vice versa.

Usage

sbroker provides configurable queues defined by sbroker:queue_spec()s. A queue_spec() takes the form:

{Module, Args}

Module is an sbroker_queue callback module to queue. The following callback modules are provided: sbroker_drop_queue, sbroker_timeout_queue and sbroker_codel_queue.

Args is the argument passed to the callback module. Information about the different backends and their arguments are avaliable in the documentation.

An sbroker is started using sbroker:start_link/3,4:

sbroker:start_link(Module, Args, Opts).
sbroker:start_link(Name, Module, Args, Opts).

The sbroker will call Module:init(Args), which should return the specification for the sbroker:

init(_) ->
    {ok, {AskQueueSpec, AskRQueueSpec, Timeout}}.

AskQueueSpec is the queue_spec for the queue containing processes calling ask/1. The queue is referred to as the ask queue. Similarly AskRQueueSpec is the queue_spec for the queue contaning processes calling ask_r/1, and the queue is referred to as the ask_r queue.

Timeout is the timeout, in milliseconds, that the broker polls the active queue after a period of inactivity. Note that timeout queue management can occur on every enqueue and dequeue, and is not reliant on the Timeout. Setting a suitable timeout ensures that active queue management can occur if no processes are enqueued or dequeued for a period of time.

For example:

-module(sbroker_example).

-behaviour(sbroker).

-export([start_link/0]).
-export([init/1]).

start_link() ->
    sbroker:start_link(?MODULE, undefined, [{time_unit, milli_seconds}]).

init(_) ->
    QueueSpec = {sbroker_timeout_queue, {out, 200, drop, 16}},
    {ok, {QueueSpec, QueueSpec, 100}}.

sbroker_example:start_link/0 will start an sbroker with queues configured by QueueSpec.

This configuration uses the sbroker_timeout_queue callback module which drops requests when they have been in the queue for longer than a time limit - in this case 200 milliseconds. out sets the queue to FIFO. drop sets the queue to drop processes from the head of the queue (head drop) when the maximum size (16) is reached. The broker timeout is 100 milliseconds, which means that queue management is applied to the active queue after 100 milliseconds of inactivity. This value is always in milliseconds, regardless of the time_unit in the start options.

To use this sbroker:

{ok, Broker} = sbroker_example:start_link(),
Pid = spawn_link(fun() -> sbroker:ask_r(Broker) end),
{go, _Ref, Pid, _, _} = sbroker:ask(Broker).

Build

Rebar:

rebar compile

Rebar3:

rebar3 compile

Documentation

Available at: http://hexdocs.pm/sbroker/

Rebar builds documentation:

rebar doc

Then visit doc/index.html.

Test

Testing requires rebar3:

rebar3 ct

License

Apache License, Version 2.0