Skip to content

Commit

Permalink
[#66] Refactor Nebulex.Caching to use annotated functions via decorat…
Browse files Browse the repository at this point in the history
…ors (#67)
  • Loading branch information
cabol committed Mar 29, 2020
1 parent 38bae8c commit d11b468
Show file tree
Hide file tree
Showing 19 changed files with 443 additions and 410 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ useful and powerful features such as:
* Inspired by [Ecto][ecto]; simple and fluent API, flexible and
pluggable architecture (based on adapters).

* Built-in adapters: local (generational cache), partitioned and multi-level.
* Built-in adapters: local (generational cache), replicated, partitioned and
multi-level.

* [Caching DSL](http://hexdocs.pm/nebulex/caching-dsl.html) to implement
different [cache usage patterns][EHCache].
* [Caching Decorators/Annotations](http://hexdocs.pm/nebulex/Nebulex.Caching.Decorators.html)
to implement different [cache usage patterns][EHCache].

* Support for different distributed caching topologies, such as:
Replicated, Partitioned, Near, etc.
Expand Down Expand Up @@ -99,8 +100,9 @@ defmodule MyApp.Cache do
## Important links

* [Documentation](http://hexdocs.pm/nebulex/Nebulex.html)
* [Getting Started](http://hexdocs.pm/nebulex/getting-started.html)
* [Caching Decorators](http://hexdocs.pm/nebulex/caching-decorators.html)
* [Examples](https://github.com/cabol/nebulex_examples)
* [Ecto Integration](https://github.com/cabol/nebulex_ecto)

## Testing

Expand Down
34 changes: 20 additions & 14 deletions guides/caching-dsl.md → guides/caching-decorators.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Cache Usage Patterns via Nebulex.Caching DSL
# Cache Usage Patterns via Nebulex.Caching.Decorators

There are several common access patterns when using a cache. **Nebulex**
supports most of these patterns by means of [Nebulex.Caching DSL][DSL].
supports most of these patterns by means of [Nebulex.Caching.Decorators][Decorators].

[DSL]: https://github.com/cabol/nebulex/blob/master/lib/nebulex/caching.ex
[Decorators]: http://hexdocs.pm/nebulex/Nebulex.Caching.Decorators.html

> Most of the following documentation about caching patterns it has been taken
from [EHCache Doc][EHCache]
Expand Down Expand Up @@ -70,11 +70,11 @@ A disadvantage of using the cache-as-SoR pattern is:

* Less directly visible code-path

But how to get all this out-of-box? This is where [Nebulex.Caching DSL][DSL]
But how to get all this out-of-box? This is where the [Decorators][Decorators]
comes in. It provides a set of macros to abstract most of the logic behind
**Read-through** and **Write-through** patterns and make the implementation
extremely easy. But let's go over these patterns more in detail and how to
implement them using [Nebulex.Caching DSL][DSL].
implement them using [Nebulex Decorators][Decorators].

## Read-through

Expand All @@ -89,23 +89,26 @@ The next time the cache is asked for the value for the same key it can be
returned from the cache without using the loader (unless the entry has been
evicted or expired).

This pattern can be easily implemented using `defcacheable` macro from
[Nebulex.Caching DSL][DSL] as follows:
This pattern can be easily implemented using `cache` decorator as follows:

```elixir
defmodule MyApp.Example do
import Nebulex.Caching
use Nebulex.Caching.Decorators

alias MyApp.Cache

defcacheable get_by_name(name, age), cache: Cache, key: name do
@decorate cache(cache: Cache, key: name)
def get_by_name(name, age) do
# your logic (the loader to retrieve the value from the SoR)
end

defcacheable get_by_age(age), cache: Cache, key: age, opts: [ttl: 3600] do
@decorate cache(cache: Cache, key: age, opts: [ttl: 3600])
def get_by_age(age) do
# your logic (the loader to retrieve the value from the SoR)
end

defcacheable all(query), cache: Cache do
@decorate cache(cache: Cache)
def all(query) do
# your logic (the loader to retrieve the value from the SoR)
end
end
Expand All @@ -129,16 +132,19 @@ associated with the given key using `defupdatable`, or just delete it using

```elixir
defmodule MyApp.Example do
import Nebulex.Caching
use Nebulex.Caching.Decorators

alias MyApp.Cache

# When the data is written to the SoR, it is updated in the cache
defupdatable update(something), cache: Cache, key: something do
@decorate update(cache: Cache, key: something)
def update(something) do
# Write data to the SoR (most likely the Database)
end

# When the data is written to the SoR, it is deleted (evicted) from the cache
defevict update_something(something), cache: Cache, key: something do
@decorate evict(cache: Cache, key: something)
def update_something(something) do
# Write data to the SoR (most likely the Database)
end
end
Expand Down
2 changes: 1 addition & 1 deletion guides/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ To learn more about how multilevel-cache works, please check

## Other important guides

* [Nebulex.Caching DSL](http://hexdocs.pm/nebulex/caching-dsl.html) - Tailored
* [Nebulex.Caching DSL](http://hexdocs.pm/nebulex/caching-decorators.html) - Tailored
DSL to implement different cache usage patterns.

* [Pre and Post Hooks](http://hexdocs.pm/nebulex/hooks.html) - Ability
Expand Down
2 changes: 1 addition & 1 deletion lib/nebulex/adapter/hash_slot.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule Nebulex.Adapter.HashSlot do
@moduledoc """
@moduledoc ~S"""
This behaviour provides a callback to compute the hash slot for a specific
key based on the number of slots/nodes.
Expand Down
2 changes: 1 addition & 1 deletion lib/nebulex/adapter/persistence.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule Nebulex.Adapter.Persistence do
@moduledoc """
@moduledoc ~S"""
Specifies the adapter persistence API.
## Default implementation
Expand Down
2 changes: 1 addition & 1 deletion lib/nebulex/adapter/transaction.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule Nebulex.Adapter.Transaction do
@moduledoc """
@moduledoc ~S"""
Specifies the adapter transactions API.
## Default implementation
Expand Down
2 changes: 1 addition & 1 deletion lib/nebulex/adapters/local.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule Nebulex.Adapters.Local do
@moduledoc """
@moduledoc ~S"""
Adapter module for Local Generational Cache.
It uses [Shards](https://github.com/cabol/shards) as in-memory backend
Expand Down
30 changes: 15 additions & 15 deletions lib/nebulex/adapters/local/generation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@ defmodule Nebulex.Adapters.Local.Generation do
These options are configured via the built-in local adapter
(`Nebulex.Adapters.Local`):
* `:gc_interval` - Interval time in seconds to garbage collection to run,
delete the oldest generation and create a new one. If this option is
not set, garbage collection is never executed, so new generations
must be created explicitly, e.g.: `new(cache, [])`.
* `:allocated_memory` - Max size in bytes allocated for a cache generation.
If this option is set and the configured value is reached, a new generation
is created so the oldest is deleted and force releasing memory space.
If it is not set (`nil`), the cleanup check to release memory is not
performed (the default).
* `:gc_cleanup_interval` - The number of writes needed to run the cleanup
check. Once this value is reached and only if `allocated_memory` option
is set, the cleanup check is performed. Defaults to `10`, so after 10
write operations the cleanup check is performed.
* `:gc_interval` - Interval time in seconds to garbage collection to run,
delete the oldest generation and create a new one. If this option is
not set, garbage collection is never executed, so new generations
must be created explicitly, e.g.: `new(cache, [])`.
* `:allocated_memory` - Max size in bytes allocated for a cache generation.
If this option is set and the configured value is reached, a new generation
is created so the oldest is deleted and force releasing memory space.
If it is not set (`nil`), the cleanup check to release memory is not
performed (the default).
* `:gc_cleanup_interval` - The number of writes needed to run the cleanup
check. Once this value is reached and only if `allocated_memory` option
is set, the cleanup check is performed. Defaults to `10`, so after 10
write operations the cleanup check is performed.
"""

defmodule State do
Expand Down
2 changes: 1 addition & 1 deletion lib/nebulex/adapters/multilevel.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule Nebulex.Adapters.Multilevel do
@moduledoc """
@moduledoc ~S"""
Adapter module for Multi-level Cache.
This is just a simple layer on top of local or distributed cache
Expand Down
2 changes: 1 addition & 1 deletion lib/nebulex/adapters/partitioned.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule Nebulex.Adapters.Partitioned do
@moduledoc """
@moduledoc ~S"""
Built-in adapter for partitioned cache topology.
A partitioned cache is a clustered, fault-tolerant cache that has linear
Expand Down
2 changes: 1 addition & 1 deletion lib/nebulex/adapters/replicated.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule Nebulex.Adapters.Replicated do
@moduledoc """
@moduledoc ~S"""
Built-in adapter for replicated cache topology.
The replicated cache excels in its ability to handle data replication,
Expand Down
2 changes: 1 addition & 1 deletion lib/nebulex/cache.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule Nebulex.Cache do
@moduledoc """
@moduledoc ~S"""
Cache Main Interface.
A Cache maps to an underlying implementation, controlled by the
Expand Down
Loading

0 comments on commit d11b468

Please sign in to comment.