README.md

<img src="http://38.media.tumblr.com/db32471b7c8870cbb0b2cc173af283bb/tumblr_inline_nm9x9u6u261rw7ney_540.gif" height="170" width="100%" />


# ExShards

This is a wrapper on top of [ETS](http://erlang.org/doc/man/ets.html) and [Shards](https://github.com/cabol/shards).

[Shards](https://github.com/cabol/shards) is a simple library to scale-out ETS tables, which implements the same ETS API.
Taking advantage of this, what **ExShards** does is provides a wrapper to use either `ets` or
`shards` totally transparent.


## Installation and Usage

To start playing with `ex_shards` you just have to follow these simple steps:

  1. Add ex_shards to your list of dependencies in `mix.exs`:

  ```elixir
  def deps do
    [{:ex_shards, "~> 0.1.0"}]
  end
  ```

  2. Because `ex_shards` uses `shards`, make sure that `shards` is started before your application:

  ```elixir
  def application do
    [applications: [:shards]]
  end
  ```

## Build

    $ git clone https://github.com/cabol/ex_shards.git
    $ cd ex_shards
    $ mix deps.get && mix compile


## Getting Started!

Start an Elixir console:

    $ iex -S mix

Once into the Elixir console:

```elixir
# create a table with default options
> ExShards.new :mytab
:mytab

> ExShards.insert :mytab, [k1: 1, k2: 2, k3: 3]
true

> for k <- [:k1, :k2, :k3] do
[{_, v}] = ExShards.lookup(:mytab, k)
v
end
[1, 2, 3]

> ExShards.delete :mytab, :k3
true
> ExShards.lookup :mytab, :k3
[]

# let's create another table
> ExShards.new :mytab2, [{:n_shards, 4}]
:mytab2

# start the observer so you can see how shards behaves
> :observer.start
:ok
```

As you might have noticed, it's extremely easy, such as you were using **ETS** API directly.


## Distributed ExShards

Let's see how **ExShards** works in distributed fashion.

**1.** Let's start 3 Elixir consoles running ExShards:

Node `a`:

```
$ iex --sname a@localhost -S mix
```

Node `b`:

```
$ iex --sname b@localhost -S mix
```

Node `c`:

```
$ iex --sname c@localhost -S mix
```

**2.** Create a table with global scope (`scope: :g`) on each node and then join them.

```elixir
> ExShards.new :mytab, scope: :g, nodes: [:b@localhost, :c@localhost]
:mytab

> ExShards.get_nodes :mytab
[:a@localhost, :b@localhost, :c@localhost]
```

**3.** Now **ExShards** cluster is ready, let's do some basic operations:

From node `a`:

```elixir
> ExShards.insert :mytab, k1: 1, k2: 2
true
```

From node `b`:

```elixir
> ExShards.insert :mytab, k3: 3, k4: 4
true
```

From node `c`:

```elixir
> ExShards.insert :mytab, k5: 5, k6: 6
true
```

Now, from any of previous nodes:

```elixir
> for k <- [:k1, :k2, :k3, :k4, :k5, :k6] do
[{_, v}] = ExShards.lookup(:mytab, k)
v
end
[1, 2, 3, 4, 5, 6]
```

All nodes should return the same result.

Let's do some deletions, from any node:

```elixir
> ExShards.delete :mytab, :k6
true
```

From any node:

```elixir
> ExShards.lookup :mytab, :k6
[]
```

Let's check again all:

```elixir
> for k <- [:k1, :k2, :k3, :k4, :k5] do
[{_, v}] = ExShards.lookup(:mytab, k)
v
end
[1, 2, 3, 4, 5]
```


## References

For more information about `shards` you can go to these links:

 * [shards](https://github.com/cabol/shards): Original Erlang project.
 * [API Reference](http://cabol.github.io/shards): Shards API Reference.
 * [Blog Post about Shards](http://cabol.github.io/posts/2016/04/14/sharding-support-for-ets.html).


## Copyright and License

Copyright (c) 2016 Carlos Andres Bolaños R.A.

**ExShards** source code is licensed under the [MIT License](LICENSE.md).