# Keep your ETS tables safe and warm with a sweet Blanket.

[![Build Status](](

If you use ETS with Elixir and Erlang, you know that an ETS table is bound to a process, and that if this process chrashes, the tables vanishes. All data is lost.

The simplest thing to do is to start a process responsible for owning the table, and do all actual table operations on another process. But this requires coodination between the two process, public named tables with an unique name. Sometimes, you need an undefined amount of private or protected unnamed tables.

More informations on theese problems and a simple solution to them can be found on Steve Vinoski's Blog here : [Don't Lose Your ets Tables](

You can also look at an Erlang implementation of the solution [on github](

Or you can go the simple way and use Blanket.

## Installation

Just define	the `:blanket` dependency in your project's `mix.exs` and require the application to be started.

  defp deps do
    [{:blanket, "~> 0.3.1"}]

  def application do
    [mod: {MyApp, []},
     applications: [:blanket]]

## Documentation

The documentation can be found on [Hex Docs](

## Example

defmodule MyApp.TableOwner do
  use GenServer

  # 1. Create your process with the table reference being part of the child
  # spec, so your process can be restarted with the same reference. Table
  # reference is not a table identifier returned by but a term to
  # identify the table in blanket. It must be unique but can be any term. Best
  # is to use make_ref() for dynamic tables, and an atom like __MODULE__ for
  # known tables.

  def create(table_ref) do
    child_spec = Supervisor.Spec.worker(__MODULE__, [table_ref])
    Supervisor.start_child(MyApp.Supervisor, child_spec)

  def start_link(table_ref) do
    GenServer.start_link(__MODULE__, [table_ref])

  # 2. Create the table on the server side. If your process crashes, the table
  # will be protected by a heir, and if you claim the table again with the same
  # reference, the existing table will be returned.

  def init([table_ref]) do
    {:ok, tab} = Blanket.claim_table(tref, create_table: fn() ->
      tab =
      {:ok, tab}
    {:ok, %State{tab: tab}}

  # 3. If you want to use temporary tables, just tell Blanket to forget about
  # the table before terminating your process.

  def terminate(:normal, %State{tab: tab}) do
    :ok = Blanket.abandon_table(tab)
  def terminate(reason, state) do
    # handle other failures