Skip to content

Commit

Permalink
Updates based on new changes introduced since Elixir 1.5
Browse files Browse the repository at this point in the history
  • Loading branch information
cabol committed Jul 12, 2018
1 parent e750fd3 commit 1715de9
Show file tree
Hide file tree
Showing 30 changed files with 484 additions and 404 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
language: elixir
elixir:
- 1.4
- 1.5
- 1.6
otp_release:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ defmodule MyApp do
import Supervisor.Spec

children = [
supervisor(MyApp.Cache, [])
{MyApp.Cache, []}
]

opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Expand Down
7 changes: 7 additions & 0 deletions bench/dist_bench.exs
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,11 @@ defmodule DistBench do
Dist.update_counter(bench_context, 1)
:ok
end

bench "transaction" do
Dist.transaction(fn ->
Dist.update_counter(bench_context, 1)
:ok
end, keys: [1])
end
end
7 changes: 7 additions & 0 deletions bench/local_bench.exs
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,11 @@ defmodule LocalBench do
Cache.update_counter(bench_context, 1)
:ok
end

bench "transaction" do
Cache.transaction(fn ->
Cache.update_counter(bench_context, 1)
:ok
end, keys: [1])
end
end
135 changes: 96 additions & 39 deletions guides/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ changing the `deps` definition in that file to this:

```elixir
defp deps do
[{:nebulex, "~> 1.0.0-rc.3"}]
[
{:nebulex, "~> 1.0.0"}
]
end
```

Expand Down Expand Up @@ -83,6 +85,8 @@ supervisor within the application's supervision tree, which we can do in
`lib/blog/application.ex` (or `lib/blog.ex` for elixir versions `< 1.4.0`),
inside the `start/2` function:

`Elixir < 1.5.0`:

```elixir
def start(_type, _args) do
import Supervisor.Spec, warn: false
Expand All @@ -94,6 +98,17 @@ def start(_type, _args) do
...
```

`Elixir >= 1.5.0`:

```elixir
def start(_type, _args) do
children = [
Blog.Cache,
]

...
```

This piece of configuration will start the Nebulex process which receives and
executes our application's commands. Without it, we wouldn't be able to use
the cache at all!
Expand Down Expand Up @@ -267,7 +282,7 @@ request to return either the key, value or object.
## Distributed Cache

Nebulex provides the adapter `Nebulex.Adapters.Dist`, which allows to setup a
distributed cache.
partitioned cache topology.

Let's setup our distributed cache by running this command:

Expand All @@ -276,7 +291,7 @@ mix nebulex.gen.cache -c Blog.DistCache -a Nebulex.Adapters.Dist
```

This command will generate the configuration required to use our distributed
cache. Within the `config/config.exs`:
cache; it is defined in `config/config.exs`:

```elixir
config :blog, Blog.DistCache,
Expand All @@ -285,53 +300,77 @@ config :blog, Blog.DistCache,
node_picker: Nebulex.Adapters.Dist
```

Replace the `local` config value `:YOUR_LOCAL_CACHE` by an existing local cache,
for example, we can set the local cache we created previously or create a new
one. Let's create a new one:
Replace the `local` config value `:YOUR_LOCAL_CACHE` by an existing local cache
(e.g.: we can set the local cache we created previously), or create a new
one (we will create a new one within `Blog.DistCache`).

The `Blog.DistCache` module is defined in `lib/blog/dist_cache.ex` by our
`mix nebulex.gen.cache` command:

```elixir
defmodule Blog.DistCache do
use Nebulex.Cache, otp_app: :blog
end
```
mix nebulex.gen.cache -c Blog.LocalCache

As mentioned previously, let's add the local backend (local cache):

```elixir
defmodule Blog.DistCache do
use Nebulex.Cache, otp_app: :blog

defmodule Primary do
use Nebulex.Cache, otp_app: :blog
end
end
```

Now let's replace the `local` config value `:YOUR_LOCAL_CACHE` by our new local
cache:
Now we have to add the new local cache to the config, and also replace the
`local` config value `:YOUR_LOCAL_CACHE` by our new local cache in the
distributed cache config.

```elixir
# Local backend for the distributed cache
config :blog, Blog.DistCache.Primary,
adapter: Nebulex.Adapters.Local,
gc_interval: 86_400 # 24 hrs

# Distributed Cache
config :blog, Blog.DistCache,
adapter: Nebulex.Adapters.Dist,
local: Blog.LocalCache,
local: Blog.DistCache.Primary,
node_picker: Nebulex.Adapters.Dist
```

The `Blog.DistCache` module is defined in `lib/blog/dist_cache.ex` by our
`mix nebulex.gen.cache` command:
And remember to setup the `Blog.DistCache` and its local backend
`Blog.DistCache.Primary` as supervisors within the application's
supervision tree (such as we did it previously):

`Elixir < 1.5.0`:

```elixir
defmodule Blog.DistCache do
use Nebulex.Cache, otp_app: :blog
end
```
def start(_type, _args) do
import Supervisor.Spec, warn: false

And the `Blog.LocalCache` module is defined in `lib/blog/local_cache.ex`:
children = [
supervisor(Blog.Cache, []), # Previous created local cache
supervisor(Blog.DistCache, []), # Distributed cache
supervisor(Blog.DistCache.Primary, []) # Local cache that will be used by the distributed cache
]

```elixir
defmodule Blog.LocalCache do
use Nebulex.Cache, otp_app: :blog
end
...
```

And remember to setup the `Blog.DistCache` and its local cache `Blog.LocalCache`
as supervisors within the application's supervision tree (such as we did it
previously):
`Elixir >= 1.5.0`:

```elixir
def start(_type, _args) do
import Supervisor.Spec, warn: false

children = [
supervisor(Blog.Cache, []), # Previous created local cache
supervisor(Blog.DistCache, []), # Distributed cache
supervisor(Blog.LocalCache, []) # Local cache that will be used by the distributed cache
Blog.Cache, # Previous created local cache
Blog.DistCache, # Distributed cache
Blog.DistCache.Primary # Local cache that will be used by the distributed cache
]

...
Expand All @@ -351,14 +390,14 @@ setup a multi-level caching hierarchy.
First, let's create a multi-level cache module:

```
mix nebulex.gen.cache -c Blog.MultilevelCache -a Nebulex.Adapters.Multilevel
mix nebulex.gen.cache -c Blog.Multilevel -a Nebulex.Adapters.Multilevel
```

This command will generate the configuration required to use our multilevel
cache. Within the `config/config.exs`:
cache; it is defined in `config/config.exs`:

```elixir
config :blog, Blog.MultilevelCache,
config :blog, Blog.Multilevel,
adapter: Nebulex.Adapters.Multilevel,
cache_model: :inclusive,
levels: []
Expand All @@ -370,27 +409,45 @@ cache, where L1 (first level) is our local cache and L2 (second level) the
distributed cache. Therefore, the configuration would be like so:

```elixir
config :blog, Blog.MultilevelCache,
config :blog, Blog.Multilevel,
adapter: Nebulex.Adapters.Multilevel,
cache_model: :inclusive,
levels: [Blog.Cache, Blog.DistCache]
```

Note that the `Blog.LocalCache` cannot be part of the levels, since it is the
cache used by `Blog.DistCache` behind scenes.
Note that the `Blog.DistCache.Primary` cannot be part of the levels, since it
is the backend used by `Blog.DistCache` behind scenes.

And remember to setup the `Blog.MultilevelCache` as a supervisor within the
And remember to setup the `Blog.Multilevel` as a supervisor within the
application's supervision tree (such as we did it previously):

`Elixir < 1.5.0`:

```elixir
def start(_type, _args) do
import Supervisor.Spec, warn: false

children = [
supervisor(Blog.Cache, []), # Previous created local cache
supervisor(Blog.DistCache, []), # Distributed cache
supervisor(Blog.DistCache.Primary, []), # Local cache that will be used by the distributed cache
supervisor(Blog.MultilevelCache, []) # Multilevel cache
]

...
```

`Elixir >= 1.5.0`:

```elixir
def start(_type, _args) do
import Supervisor.Spec, warn: false

children = [
supervisor(Blog.Cache, []), # Previous created local cache
supervisor(Blog.DistCache, []), # Distributed cache
supervisor(Blog.LocalCache, []), # Local cache that will be used by the distributed cache
supervisor(Blog.MultilevelCache, []) # Multilevel cache
Blog.Cache, # Previous created local cache
Blog.DistCache, # Distributed cache
Blog.DistCache.Primary, # Local cache that will be used by the distributed cache
Blog.Multilevel # Multilevel cache
]

...
Expand All @@ -414,7 +471,7 @@ iex> Blog.DistCache.get("foo")
Now let's retrieve the data but using the multi-level cache:

```elixir
iex> Blog.MultilevelCache.get("foo")
iex> Blog.Multilevel.get("foo")
"bar"

iex> Blog.Cache.get("foo")
Expand Down
7 changes: 5 additions & 2 deletions lib/mix/tasks/nebulex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ defmodule Mix.Tasks.Nebulex do
{_opts, args, _} = OptionParser.parse(args)

case args do
[] -> general()
_ -> Mix.raise "Invalid arguments, expected: mix nebulex"
[] ->
general()

_ ->
Mix.raise "Invalid arguments, expected: mix nebulex"
end
end

Expand Down
4 changes: 4 additions & 0 deletions lib/mix/tasks/nebulex.gen.cache.ex
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ defmodule Mix.Tasks.Nebulex.Gen.Cache do
Mix.shell.info [:green, "* updating ", :reset, "config/config.exs"]
File.write! "config/config.exs",
String.replace(contents, "use Mix.Config", config_template(opts))

{:error, _} ->
create_file "config/config.exs", config_template(opts)
end
Expand Down Expand Up @@ -90,10 +91,13 @@ defmodule Mix.Tasks.Nebulex.Gen.Cache do
case opts[:adapter] do
Nebulex.Adapters.Local ->
local_config_template(opts)

Nebulex.Adapters.Dist ->
dist_config_template(opts)

Nebulex.Adapters.Multilevel ->
multilevel_config_template(opts)

_ ->
default_config_template(opts)
end
Expand Down
17 changes: 6 additions & 11 deletions lib/nebulex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,13 @@ defmodule Nebulex do
edit the `start/2` function to start the repo as a supervisor on your
application's supervisor:
defmodule MyApp do
use Application
def start(_type, _args) do
children = [
{MyApp.Cache, []}
]
def start(_type, _args) do
import Supervisor.Spec
children = [
supervisor(MyApp.MyCache, [])
]
...
end
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
## Object
Expand Down
6 changes: 3 additions & 3 deletions lib/nebulex/adapter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ defmodule Nebulex.Adapter do
@macrocallback __before_compile__(env :: Macro.Env.t) :: Macro.t

@doc """
Returns the children specs that starts the adapter process.
Initializes the adapter supervision tree by returning the children
"""
@callback children_specs(cache, opts) :: [Supervisor.Spec.spec]
@callback init(cache, opts) :: {:ok, [:supervisor.child_spec()]}

@doc """
Retrieves a single object from Cache.
Expand Down Expand Up @@ -104,7 +104,7 @@ defmodule Nebulex.Adapter do
See `Nebulex.Cache.get_and_update/3`.
"""
@callback get_and_update(cache, key, (value -> {get, update} | :pop), opts) ::
no_return | {get, update} when get: value, update: return
no_return | {get, update} when get: value, update: return

@doc """
Updates the cached `key` with the given function.
Expand Down
Loading

0 comments on commit 1715de9

Please sign in to comment.