barenboim v0.1.0 Barenboim

Barenboim is prepared to tackle with data streaming dependencies in concurrent flows.

If your application works with a data streaming and your incoming events could have dependencies between them, the app can have problems about when the dependency data is ready. Reasons:

  • The Application which is sending the data is not sending the data in the right order
  • Your Application is treating the data concurrently therefore the order is not ensured.

Configuration

Barenboim uses poolboy and you can configure it depending on your needs:

  config :barenboim,
    pool_domain: :global,     # default :local
    pool_size: 20,            # default 10
    max_overflow: 3           # default 5

How to use it

Define the function that will retrieve the dependency data where dependency_id is the id of your data and call Barenboim.get_data. You can also specify a time out in milliseconds.

fun = fn(dependency_id) -> MyDataModule.get(dependency_id) end
{:ok, data} = Barenboim.get_data(dependency_id, fun)

Meanwhile, the flow that is processing a new event has to call ready function when the data is available for others.

  Barenboim.ready(dependency_id)

Summary

Functions

This function will return the dependency data when is ready

It has to be called when the data dependency is ready to be used by its dependents

Functions

get_data(dependency_id, fun, time_to_live \\ nil)
get_data(any, (any -> any), integer | nil) ::
  {:ok, any} |
  {:timeout, any}

This function will return the dependency data when is ready.

  • dependency_id is the reference of the dependency data
  • fun is the function that will get the dependency data. If you don’t need the data in that moment, only ensure that the data is ready, your fun function could only be a data checker fn(dependency) -> MyDataModule.exist(dependency) end. Barenboim will consider a ready data when executing fun it retrieves a value different than:

    • nil
    • false
    • [] empty list
    • {} empty tuple
    • %{} empty map

If some of these values are valid for your application, use encapsulation in your function, example: {:ok, []}

  • if timeout is a valid integer, Barenboim will only wait for the data these milliseconds. If the value does not arrive before the time out, it will return {:timeout, data} where data will be the return of fun at that moment.
  fun = fn(dependency_id) -> MyDataModule.get(dependency_id) end
  case Barenboim.get_data(dependency_id, fun) do
    {:ok, data} -> process(data)
    {:timeout, empty_data} -> go_on()
  end
ready(dependency_id)
ready(any) :: any

It has to be called when the data dependency is ready to be used by its dependents.