Skip to content

Commit 7ed4639

Browse files
committed
Introduce basic distribution support
1 parent dfd2aef commit 7ed4639

14 files changed

Lines changed: 339 additions & 79 deletions

File tree

lib/cachex.ex

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ defmodule Cachex do
7777
get: [ 2, 3 ],
7878
get_and_update: [ 3, 4 ],
7979
incr: [ 2, 3, 4 ],
80-
inspect: [ 2 ],
80+
inspect: [ 2, 3 ],
8181
invoke: [ 3, 4 ],
8282
keys: [ 1, 2 ],
8383
load: [ 2, 3 ],
@@ -351,7 +351,7 @@ defmodule Cachex do
351351
"""
352352
@spec clear(cache, Keyword.t) :: { status, integer }
353353
def clear(cache, options \\ []) when is_list(options),
354-
do: Router.dispatch(cache, { :clear, [ options ] })
354+
do: Router.call(cache, { :clear, [ options ] })
355355

356356
@doc """
357357
Retrieves the number of unexpired records in a cache.
@@ -372,7 +372,7 @@ defmodule Cachex do
372372
"""
373373
@spec count(cache, Keyword.t) :: { status, number }
374374
def count(cache, options \\ []) when is_list(options),
375-
do: Router.dispatch(cache, { :count, [ options ] })
375+
do: Router.call(cache, { :count, [ options ] })
376376

377377
@doc """
378378
Decrements an entry in the cache.
@@ -430,7 +430,7 @@ defmodule Cachex do
430430
"""
431431
@spec del(cache, any, Keyword.t) :: { status, boolean }
432432
def del(cache, key, options \\ []) when is_list(options),
433-
do: Router.dispatch(cache, { :del, [ key, options ] })
433+
do: Router.call(cache, { :del, [ key, options ] })
434434

435435
@doc """
436436
Serializes a cache to a location on a filesystem.
@@ -466,7 +466,7 @@ defmodule Cachex do
466466
@spec dump(cache, binary, Keyword.t) :: { status, any }
467467
def dump(cache, path, options \\ [])
468468
when is_binary(path) and is_list(options),
469-
do: Router.dispatch(cache, { :dump, [ path, options ] })
469+
do: Router.call(cache, { :dump, [ path, options ] })
470470

471471
@doc """
472472
Determines whether a cache contains any entries.
@@ -488,7 +488,7 @@ defmodule Cachex do
488488
"""
489489
@spec empty?(cache, Keyword.t) :: { status, boolean }
490490
def empty?(cache, options \\ []) when is_list(options),
491-
do: Router.dispatch(cache, { :empty?, [ options ] })
491+
do: Router.call(cache, { :empty?, [ options ] })
492492

493493
@doc """
494494
Executes multiple functions in the context of a cache.
@@ -542,7 +542,7 @@ defmodule Cachex do
542542
"""
543543
@spec exists?(cache, any, Keyword.t) :: { status, boolean }
544544
def exists?(cache, key, options \\ []) when is_list(options),
545-
do: Router.dispatch(cache, { :exists?, [ key, options ] })
545+
do: Router.call(cache, { :exists?, [ key, options ] })
546546

547547
@doc """
548548
Places an expiration time on an entry in a cache.
@@ -566,7 +566,7 @@ defmodule Cachex do
566566
@spec expire(cache, any, number, Keyword.t) :: { status, boolean }
567567
def expire(cache, key, expiration, options \\ [])
568568
when (is_nil(expiration) or is_number(expiration)) and is_list(options),
569-
do: Router.dispatch(cache, { :expire, [ key, expiration, options ] })
569+
do: Router.call(cache, { :expire, [ key, expiration, options ] })
570570

571571
@doc """
572572
Updates an entry in a cache to expire at a given time.
@@ -645,7 +645,7 @@ defmodule Cachex do
645645
Overseer.enforce(cache) do
646646
case fallback || fallback(cache(cache, :fallback), :default) do
647647
val when is_function(val) ->
648-
Router.dispatch(cache, { :fetch, [ key, val, options ] })
648+
Router.call(cache, { :fetch, [ key, val, options ] })
649649
_na ->
650650
error(:invalid_fallback)
651651
end
@@ -667,7 +667,7 @@ defmodule Cachex do
667667
"""
668668
@spec get(cache, any, Keyword.t) :: { atom, any }
669669
def get(cache, key, options \\ []) when is_list(options),
670-
do: Router.dispatch(cache, { :get, [ key, options ] })
670+
do: Router.call(cache, { :get, [ key, options ] })
671671

672672
@doc """
673673
Retrieves and updates an entry in a cache.
@@ -696,7 +696,7 @@ defmodule Cachex do
696696
@spec get_and_update(cache, any, function, Keyword.t) :: { :commit | :ignore, any }
697697
def get_and_update(cache, key, update_function, options \\ [])
698698
when is_function(update_function) and is_list(options),
699-
do: Router.dispatch(cache, { :get_and_update, [ key, update_function, options ] })
699+
do: Router.call(cache, { :get_and_update, [ key, update_function, options ] })
700700

701701
@doc """
702702
Retrieves a list of all entry keys from a cache.
@@ -718,7 +718,7 @@ defmodule Cachex do
718718
"""
719719
@spec keys(cache, Keyword.t) :: { status, [ any ] }
720720
def keys(cache, options \\ []) when is_list(options),
721-
do: Router.dispatch(cache, { :keys, [ options ] })
721+
do: Router.call(cache, { :keys, [ options ] })
722722

723723
@doc """
724724
Increments an entry in the cache.
@@ -751,7 +751,7 @@ defmodule Cachex do
751751
@spec incr(cache, any, integer, Keyword.t) :: { status, integer }
752752
def incr(cache, key, amount \\ 1, options \\ [])
753753
when is_integer(amount) and is_list(options),
754-
do: Router.dispatch(cache, { :incr, [ key, amount, options ] })
754+
do: Router.call(cache, { :incr, [ key, amount, options ] })
755755

756756
@doc """
757757
Inspects various aspects of a cache.
@@ -848,9 +848,9 @@ defmodule Cachex do
848848
{ :ok, 1328 }
849849
850850
"""
851-
@spec inspect(cache, atom | tuple) :: { status, any }
852-
def inspect(cache, option),
853-
do: Router.dispatch(cache, { :inspect, [ option ] })
851+
@spec inspect(cache, atom | tuple, Keyword.t) :: { status, any }
852+
def inspect(cache, option, options \\ []),
853+
do: Router.call(cache, { :inspect, [ option, options ] })
854854

855855
@doc """
856856
Invokes a custom command against a cache entry.
@@ -876,7 +876,7 @@ defmodule Cachex do
876876
"""
877877
@spec invoke(cache, atom, any, Keyword.t) :: any
878878
def invoke(cache, cmd, key, options \\ []) when is_list(options),
879-
do: Router.dispatch(cache, { :invoke, [ cmd, key, options ] })
879+
do: Router.call(cache, { :invoke, [ cmd, key, options ] })
880880

881881
@doc """
882882
Deserializes a cache from a location on a filesystem.
@@ -911,7 +911,7 @@ defmodule Cachex do
911911
@spec load(cache, binary, Keyword.t) :: { status, any }
912912
def load(cache, path, options \\ [])
913913
when is_binary(path) and is_list(options),
914-
do: Router.dispatch(cache, { :load, [ path, options ] })
914+
do: Router.call(cache, { :load, [ path, options ] })
915915

916916
@doc """
917917
Removes an expiration time from an entry in a cache.
@@ -946,7 +946,7 @@ defmodule Cachex do
946946
"""
947947
@spec purge(cache, Keyword.t) :: { status, number }
948948
def purge(cache, options \\ []) when is_list(options),
949-
do: Router.dispatch(cache, { :purge, [ options ] })
949+
do: Router.call(cache, { :purge, [ options ] })
950950

951951
@doc """
952952
Places an entry in a cache.
@@ -975,7 +975,7 @@ defmodule Cachex do
975975
# TODO: maybe rename TTL to be expiration?
976976
@spec put(cache, any, any, Keyword.t) :: { status, boolean }
977977
def put(cache, key, value, options \\ []) when is_list(options),
978-
do: Router.dispatch(cache, { :put, [ key, value, options ] })
978+
do: Router.call(cache, { :put, [ key, value, options ] })
979979

980980
@doc """
981981
Places a batch of entries in a cache.
@@ -1007,7 +1007,7 @@ defmodule Cachex do
10071007
@spec put_many(cache, [ { any, any } ], Keyword.t) :: { status, boolean }
10081008
def put_many(cache, pairs, options \\ [])
10091009
when is_list(pairs) and is_list(options),
1010-
do: Router.dispatch(cache, { :put_many, [ pairs, options ] })
1010+
do: Router.call(cache, { :put_many, [ pairs, options ] })
10111011

10121012
@doc """
10131013
Refreshes an expiration for an entry in a cache.
@@ -1034,7 +1034,7 @@ defmodule Cachex do
10341034
"""
10351035
@spec refresh(cache, any, Keyword.t) :: { status, boolean }
10361036
def refresh(cache, key, options \\ []) when is_list(options),
1037-
do: Router.dispatch(cache, { :refresh, [ key, options ] })
1037+
do: Router.call(cache, { :refresh, [ key, options ] })
10381038

10391039
@doc """
10401040
Resets a cache by clearing the keyspace and restarting any hooks.
@@ -1076,7 +1076,7 @@ defmodule Cachex do
10761076
"""
10771077
@spec reset(cache, Keyword.t) :: { status, true }
10781078
def reset(cache, options \\ []) when is_list(options),
1079-
do: Router.dispatch(cache, { :reset, [ options ] })
1079+
do: Router.call(cache, { :reset, [ options ] })
10801080

10811081
@doc """
10821082
Deprecated implementation delegate of `put/4`.
@@ -1113,7 +1113,7 @@ defmodule Cachex do
11131113
"""
11141114
@spec size(cache, Keyword.t) :: { status, number }
11151115
def size(cache, options \\ []) when is_list(options),
1116-
do: Router.dispatch(cache, { :size, [ options ] })
1116+
do: Router.call(cache, { :size, [ options ] })
11171117

11181118
@doc """
11191119
Retrieves statistics about a cache.
@@ -1139,7 +1139,7 @@ defmodule Cachex do
11391139
"""
11401140
@spec stats(cache, Keyword.t) :: { status, %{ } }
11411141
def stats(cache, options \\ []) when is_list(options),
1142-
do: Router.dispatch(cache, { :stats, [ options ] })
1142+
do: Router.call(cache, { :stats, [ options ] })
11431143

11441144
@doc """
11451145
Creates a `Stream` of entries in a cache.
@@ -1187,7 +1187,7 @@ defmodule Cachex do
11871187
@spec stream(cache, any, Keyword.t) :: { status, Enumerable.t }
11881188
def stream(cache, query \\ Query.create(true), options \\ [])
11891189
when is_list(options),
1190-
do: Router.dispatch(cache, { :stream, [ query, options ] })
1190+
do: Router.call(cache, { :stream, [ query, options ] })
11911191

11921192
@doc """
11931193
Takes an entry from a cache.
@@ -1210,7 +1210,7 @@ defmodule Cachex do
12101210
"""
12111211
@spec take(cache, any, Keyword.t) :: { status, any }
12121212
def take(cache, key, options \\ []) when is_list(options),
1213-
do: Router.dispatch(cache, { :take, [ key, options ] })
1213+
do: Router.call(cache, { :take, [ key, options ] })
12141214

12151215
@doc """
12161216
Updates the last write time on a cache entry.
@@ -1220,7 +1220,7 @@ defmodule Cachex do
12201220
"""
12211221
@spec touch(cache, any, Keyword.t) :: { status, boolean }
12221222
def touch(cache, key, options \\ []) when is_list(options),
1223-
do: Router.dispatch(cache, { :touch, [ key, options ] })
1223+
do: Router.call(cache, { :touch, [ key, options ] })
12241224

12251225
@doc """
12261226
Executes multiple functions in the context of a transaction.
@@ -1257,7 +1257,7 @@ defmodule Cachex do
12571257
|> Overseer.update(&cache(&1, transactional: true))
12581258
end
12591259

1260-
Router.dispatch(trans_cache, { :transaction, [ keys, operation, options ] })
1260+
Router.call(trans_cache, { :transaction, [ keys, operation, options ] })
12611261
end
12621262
end
12631263

@@ -1282,7 +1282,7 @@ defmodule Cachex do
12821282
"""
12831283
@spec ttl(cache, any, Keyword.t) :: { status, number }
12841284
def ttl(cache, key, options \\ []) when is_list(options),
1285-
do: Router.dispatch(cache, { :ttl, [ key, options ] })
1285+
do: Router.call(cache, { :ttl, [ key, options ] })
12861286

12871287
@doc """
12881288
Updates an entry in a cache.
@@ -1308,7 +1308,7 @@ defmodule Cachex do
13081308
"""
13091309
@spec update(cache, any, any, Keyword.t) :: { status, any }
13101310
def update(cache, key, value, options \\ []) when is_list(options),
1311-
do: Router.dispatch(cache, { :update, [ key, value, options ] })
1311+
do: Router.call(cache, { :update, [ key, value, options ] })
13121312

13131313
###############
13141314
# Private API #

lib/cachex/actions/clear.ex

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,16 @@ defmodule Cachex.Actions.Clear do
2222
This action executes inside a transaction to ensure that there are no keys under
2323
a lock - thus ensuring consistency (any locks are executed sequentially).
2424
"""
25-
def execute(cache(name: name) = cache, _options) do
25+
def execute(cache(name: name) = cache, options) do
2626
Locksmith.transaction(cache, [], fn ->
27+
options =
28+
options
29+
|> Keyword.take([ :local ])
30+
|> Enum.concat(const(:notify_false))
31+
2732
evicted =
2833
cache
29-
|> Cachex.size(const(:notify_false))
34+
|> Cachex.size(options)
3035
|> handle_evicted
3136

3237
true = :ets.delete_all_objects(name)

lib/cachex/actions/empty.ex

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,13 @@ defmodule Cachex.Actions.Empty do
2121
Internally this action is delegated through to the `size()` command and the
2222
returned numeric value is just "cast" to a boolean value.
2323
"""
24-
def execute(cache() = cache, _options) do
25-
{ :ok, size } = Cachex.size(cache, const(:notify_false))
24+
def execute(cache() = cache, options) do
25+
options =
26+
options
27+
|> Keyword.take([ :local ])
28+
|> Enum.concat(const(:notify_false))
29+
30+
{ :ok, size } = Cachex.size(cache, options)
2631
{ :ok, size == 0 }
2732
end
2833
end

lib/cachex/actions/inspect.ex

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ defmodule Cachex.Actions.Inspect do
2020
@type option :: { :expired, :count } | { :expired, :keys } |
2121
{ :janitor, :last } | { :memory, :bytes } |
2222
{ :memory, :binary } | { :memory, :words } |
23-
{ :record, any } | :cache
23+
{ :entry, any } | :cache
2424

2525
# pre-calculated memory size
2626
@memory_exponent :math.log(1024)
@@ -51,21 +51,21 @@ defmodule Cachex.Actions.Inspect do
5151
There are many options broken up by function head, so please see the source
5252
commands for definition for further documentation.
5353
"""
54-
def execute(cache, option)
54+
def execute(cache, option, options)
5555

5656
# Retrieves the internal state of the cache.
5757
#
5858
# This is relatively easy to get via other methods, but it's available here
5959
# as the "best" way for a developer to do so (outside of the internal API).
60-
def execute(cache(name: name), :cache),
60+
def execute(cache(name: name), :cache, _options),
6161
do: { :ok, Overseer.retrieve(name) }
6262

6363
# Retrieves a raw entry from the cache table.
6464
#
6565
# This is useful when you need access to a record which may have expired. If
6666
# the entry does not exist, a nil value will be returned instead. Expirations
6767
# are not taken into account (either lazily or otherwise) on this read call.
68-
def execute(cache(name: name), { :entry, key }) do
68+
def execute(cache(name: name), { :entry, key }, _options) do
6969
case :ets.lookup(name, key) do
7070
[ ] -> { :ok, nil }
7171
[e] -> { :ok, e }
@@ -77,15 +77,15 @@ defmodule Cachex.Actions.Inspect do
7777
# The number of entries returned represents the number of records which will
7878
# be removed on the next run of the Janitor service. It does not track the
7979
# number of expired records which have already been purged or removed.
80-
def execute(cache(name: name), { :expired, :count }),
80+
def execute(cache(name: name), { :expired, :count }, _options),
8181
do: { :ok, :ets.select_count(name, Query.expired(true)) }
8282

8383
# Returns the keys of expired entries currently inside the cache.
8484
#
8585
# This is essentially the same as the definition above, except that it will
8686
# return the list of entry keys rather than just a count. Naturally this is
8787
# an expensive call and should really only be used when debugging.
88-
def execute(cache(name: name), { :expired, :keys }),
88+
def execute(cache(name: name), { :expired, :keys }, _options),
8989
do: { :ok, :ets.select(name, Query.expired(:key)) }
9090

9191
# Returns information about the last run of the Janitor service.
@@ -95,36 +95,36 @@ defmodule Cachex.Actions.Inspect do
9595
# schema is defined in the `Cachex.Services.Janitor` module.
9696
#
9797
# In the case the Janitor service is not running, an error will be returned.
98-
def execute(cache() = cache, { :janitor, :last }),
98+
def execute(cache() = cache, { :janitor, :last }, _options),
9999
do: Janitor.last_run(cache)
100100

101101
# Retrieves the current size of the backing cache table in bytes.
102102
#
103103
# This should be treated as an estimation as it's rounded based on
104104
# the number of words used to maintain the cache.
105-
def execute(cache() = cache, { :memory, :bytes }) do
106-
{ :ok, mem_words } = execute(cache, { :memory, :words })
105+
def execute(cache() = cache, { :memory, :bytes }, options) do
106+
{ :ok, mem_words } = execute(cache, { :memory, :words }, options)
107107
{ :ok, mem_words * :erlang.system_info(:wordsize) }
108108
end
109109

110110
# Retrieves the current size of the backing cache table in a readable format.
111111
#
112112
# This should be treated as an estimation as it's rounded based on the number
113113
# of words used to maintain the cache.
114-
def execute(cache() = cache, { :memory, :binary }) do
115-
{ :ok, bytes } = execute(cache, { :memory, :bytes })
114+
def execute(cache() = cache, { :memory, :binary }, options) do
115+
{ :ok, bytes } = execute(cache, { :memory, :bytes }, options)
116116
{ :ok, bytes_to_readable(bytes) }
117117
end
118118

119119
# Retrieves the current size of the backing cache table in machine words.
120120
#
121121
# It's unlikely the caller will want to use this directly, but as it's used
122122
# by other inspection methods there's no harm in exposing it in the API.
123-
def execute(cache(name: name), { :memory, :words }),
123+
def execute(cache(name: name), { :memory, :words }, _options),
124124
do: { :ok, :ets.info(name, :memory) }
125125

126126
# Catch-all to return an error.
127-
def execute(_cache, _option),
127+
def execute(_cache, _option, _options),
128128
do: error(:invalid_option)
129129

130130
# Converts a number of bytes to a binary representation.

0 commit comments

Comments
 (0)