@@ -8,36 +8,63 @@ defmodule Mentat do
88 use Supervisor
99 use Oath
1010
11- @ type cache_opts ( ) :: Keyword . t ( )
11+ @ cache_opts NimbleOptions . new! ( [
12+ name: [
13+ type: :atom ,
14+ doc: "The cache name as an atom" ,
15+ required: true
16+ ] ,
17+ cleanup_interval: [
18+ type: :pos_integer ,
19+ doc: "How often the janitor process will remove old keys." ,
20+ default: 5_000
21+ ] ,
22+ ets_args: [
23+ type: :any ,
24+ doc: "Additional arguments to pass to `:ets.new/2`" ,
25+ default: [ ]
26+ ] ,
27+ ttl: [
28+ type: :timeout ,
29+ doc: "The default ttl for all keys. Defaults to `:infinity`." ,
30+ default: :infinity
31+ ] ,
32+ limit: [
33+ type: :keyword_list ,
34+ doc: "Limits to the number of keys a cache will store." ,
35+ keys: [
36+ size: [
37+ type: :pos_integer ,
38+ required: true ,
39+ doc: "The maximum number of values to store in the cache"
40+ ] ,
41+ reclaim: [
42+ type: :float ,
43+ default: 0.1 ,
44+ doc: "The percentage of keys to reclaim if the limit is exceeded."
45+ ]
46+ ]
47+ ] ,
48+ clock: [
49+ type: :any ,
50+ doc: false ,
51+ type_doc: false ,
52+ default: System
53+ ]
54+ ] )
55+
56+ @ default_limit % { reclaim: 0.1 }
57+
58+ @ type cache_opts ( ) :: unquote ( NimbleOptions . option_typespec ( @ cache_opts ) )
1259 @ type name :: atom ( )
1360 @ type key :: term ( )
1461 @ type value :: term ( )
1562 @ type put_opts :: [
1663 { :ttl , pos_integer ( ) | :infinity } ,
1764 ]
1865
19- @ default_limit % { reclaim: 0.1 }
20-
2166 alias Mentat.Janitor
2267
23- defp cache_opts do
24- import Norm
25-
26- coll_of (
27- one_of ( [
28- { :name , spec ( is_atom ) } ,
29- { :cleanup_interval , spec ( is_integer and & & 1 > 0 ) } ,
30- { :ets_args , spec ( is_list ) } ,
31- { :ttl , one_of ( [ spec ( is_integer and & & 1 > 0 ) , :infinity ] ) } ,
32- { :clock , spec ( is_atom ) } ,
33- { :limit , coll_of ( one_of ( [
34- { :size , spec ( is_integer and & & 1 > 0 ) } ,
35- { :reclaim , spec ( is_float ) } ,
36- ] ) ) }
37- ] )
38- )
39- end
40-
4168 @ doc false
4269 def child_spec ( opts ) do
4370 name = opts [ :name ] || raise ArgumentError , ":name is required"
@@ -53,17 +80,11 @@ defmodule Mentat do
5380 Starts a new cache.
5481
5582 Options:
56- * `:name` - the cache name as an atom. required.
57- * `:cleanup_interval` - How often the janitor process will remove old keys. Defaults to 5_000.
58- * `:ets_args` - Additional arguments to pass to `:ets.new/2`.
59- * `:ttl` - The default ttl for all keys. Default `:infinity`.
60- * `:limit` - Limits to the number of keys a cache will store. Defaults to `:none`.
61- * `:size` - The maximum number of values to store in the cache.
62- * `:reclaim` - The percentage of keys to reclaim if the limit is exceeded. Defaults to 0.1.
83+ #{ NimbleOptions . docs ( @ cache_opts ) }
6384 """
6485 @ spec start_link ( cache_opts ( ) ) :: Supervisor . on_start ( )
6586 def start_link ( args ) do
66- args = Norm . conform !( args , cache_opts ( ) )
87+ args = NimbleOptions . validate !( args , @ cache_opts )
6788 name = args [ :name ]
6889 Supervisor . start_link ( __MODULE__ , args , name: name )
6990 end
@@ -245,12 +266,12 @@ defmodule Mentat do
245266
246267 def init ( args ) do
247268 name = args [ :name ]
248- interval = args [ :cleanup_interval ] || 5_000
269+ interval = args [ :cleanup_interval ]
249270 limit = args [ :limit ] || :none
250271 limit = if limit != :none , do: Map . merge ( @ default_limit , Map . new ( limit ) ) , else: limit
251272 ets_args = args [ :ets_args ] || [ ]
252273 clock = args [ :clock ] || System
253- ttl = args [ :ttl ] || :infinity
274+ ttl = args [ :ttl ]
254275 ^ name = :ets . new ( name , [ :set , :named_table , :public ] ++ ets_args )
255276
256277 put_config ( name , % { limit: limit , ttl: ttl , clock: clock } )
0 commit comments