Flub

Flub does Pub. Flub does Sub. Flub does PubSub, bub.

Motivation

Even in Elixir and OTP applications, close coupling modules can lead you into dark places. When one process publishes and another subscribes, neither needs to be specifically aware of the other. Additionally, extending the functionality of existing applications is much easier when new modules can just hook into existing published event streams.

Features

Usage

Simple, single event stream

iex> Flub.sub # <= subscribe for all published messages
:ok
...> Flub.pub(:test) # <= publish to all channels
:ok
...> flush
%Flub.Message{channel: Flub.AllChannels, data: :test, node: :'nonode@nohost'}
:ok
...> Flub.unsub # <= no longer receive messages
[:ok]

Multiple event streams

iex> Flub.sub(MyTopic) # <= subscribe to a particular channel
:ok
...> Flub.pub({Interesting, :data}, MyTopic) # <= publish to that channel
:ok
...> flush
%Flub.Message{channel: MyTopic, data: {Interesting, :data}, node: :'nonode@nohost'}
:ok
...> Flub.unsub(MyTopic)
:ok
...> Flub.pub({Interesting, :data}, MyTopic)
:ok
...> flush
:ok
...> # no messages received

Pattern Matching subscriptions

iex> Flub.sub(%{key: value}, MyNewTopic) # <= sub/0 and /1 are functions
** (CompileError) iex:13: you must require Flub before invoking the macro Flub.sub/2
...> require Flub
nil
...> Flub.sub(%{key: value}, MyNewTopic)
:ok
...> Flub.pub(%{key: :value, other: "other"}, MyNewTopic)
:ok
...> flush
%Flub.Message{channel: MyNewTopic, data: %{key: :value, other: "other"}, node: :'nonode@nohost'}
:ok
...> Flub.pub(%{key2: :value2}, MyNewTopic)
:ok
...> flush
:ok

API

Publish data to Subscribers :pub/1, :pub/2

Subscribe for data :sub/0, :sub/1, :sub/2, :sub/3

Unsubscribe unsub/0, unsub/1

Miscellaneous

Installation

The package can be installed as:

  1. Add Flub to your list of dependencies in mix.exs:
```elixir
def deps do
[{:flub, github: "meyercm/flub"}]
end
```
  1. Ensure Flub is started before your application:
```elixir
def application do
[applications: [:flub]]
end
```