readthis 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/lib/active_support/cache/readthis_store.rb +3 -0
- data/lib/readthis/cache.rb +38 -34
- data/lib/readthis/entity.rb +24 -12
- data/lib/readthis/errors.rb +15 -0
- data/lib/readthis/expanders.rb +4 -1
- data/lib/readthis/passthrough.rb +1 -1
- data/lib/readthis/scripts.rb +50 -0
- data/lib/readthis/serializers.rb +9 -5
- data/lib/readthis/version.rb +1 -1
- data/lib/readthis.rb +3 -3
- data/script/mexpire.lua +7 -0
- data/spec/readthis/cache_spec.rb +6 -1
- data/spec/readthis/entity_spec.rb +0 -1
- data/spec/readthis/expanders_spec.rb +0 -2
- data/spec/readthis/passthrough_spec.rb +3 -4
- data/spec/readthis/scripts_spec.rb +31 -0
- data/spec/readthis/serializers_spec.rb +17 -8
- data/spec/readthis_spec.rb +0 -2
- data/spec/spec_helper.rb +1 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff00fddcb5af28ee6566f8f9d95e69b842adbb4c
|
4
|
+
data.tar.gz: cf57c791dbf2d3c9bb4b0fe3cb3f541df00b9385
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 378c680e372e985903972f569b4402e11f1dde8b9ce1805e3bc1b78e21428fd0290f9896d186aab1014f7cc2aa0ed1c75001573e0a90dd3cfa3bdb7c11cc16f1
|
7
|
+
data.tar.gz: c41dbbf2eea8a564975510066e6ed881c1940497cd04249ed676faf935314eafd9a26b1e76c98633c69bcf8cd67d8df766730e97f3f9877d2e3c03ed600fa155
|
data/README.md
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
[](https://travis-ci.org/sorentwo/readthis)
|
3
3
|
[](https://codeclimate.com/github/sorentwo/readthis)
|
4
4
|
[](https://coveralls.io/github/sorentwo/readthis?branch=master)
|
5
|
+
[](http://inch-ci.org/github/sorentwo/readthis)
|
5
6
|
|
6
7
|
# Readthis
|
7
8
|
|
@@ -184,7 +185,8 @@ Readthis supports all of standard cache methods except for the following:
|
|
184
185
|
* `cleanup` - Redis does this with TTL or LRU already.
|
185
186
|
* `delete_matched` - You really don't want to perform key matching operations in
|
186
187
|
Redis. They are linear time and only support basic globbing.
|
187
|
-
* `mute` and `silence!` - You can subscribe to the events `/cache
|
188
|
+
* `mute` and `silence!` - You can subscribe to the events `/cache*.active_support/`
|
189
|
+
with `ActiveSupport::Notifications` to [log cache calls manually][notifications].
|
188
190
|
|
189
191
|
[notifications]: https://github.com/sorentwo/readthis/issues/22#issuecomment-142595938
|
190
192
|
|
@@ -1,6 +1,9 @@
|
|
1
1
|
require 'readthis'
|
2
2
|
|
3
3
|
module ActiveSupport
|
4
|
+
# Provided for compatibility with ActiveSupport's cache lookup behavior. When
|
5
|
+
# the ActiveSupport `cache_store` is set to `:readthis_store` it will resolve
|
6
|
+
# to `Readthis::Cache`.
|
4
7
|
module Cache
|
5
8
|
ReadthisStore ||= Readthis::Cache # rubocop:disable Style/ConstantName
|
6
9
|
end
|
data/lib/readthis/cache.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'readthis/entity'
|
2
2
|
require 'readthis/expanders'
|
3
3
|
require 'readthis/passthrough'
|
4
|
+
require 'readthis/scripts'
|
4
5
|
require 'redis'
|
5
6
|
require 'connection_pool'
|
6
7
|
|
7
8
|
module Readthis
|
8
9
|
class Cache
|
9
|
-
attr_reader :entity, :notifications, :options, :pool
|
10
|
+
attr_reader :entity, :notifications, :options, :pool, :scripts
|
10
11
|
|
11
12
|
# Provide a class level lookup of the proper notifications module.
|
12
13
|
# Instrumention is expected to occur within applications that have
|
@@ -18,15 +19,15 @@ module Readthis
|
|
18
19
|
|
19
20
|
# Creates a new Readthis::Cache object with the given options.
|
20
21
|
#
|
21
|
-
# @option [Hash] :redis Options that will be passed to the redis connection
|
22
|
-
# @option [Boolean] :compress (false) Enable or disable automatic compression
|
23
|
-
# @option [Number] :compression_threshold (8k) Minimum string size for compression
|
24
|
-
# @option [Number] :expires_in The number of seconds until an entry expires
|
25
|
-
# @option [Boolean] :refresh (false) Automatically refresh key expiration
|
26
|
-
# @option [Module] :marshal (Marshal) Module that responds to `dump` and `load`
|
27
|
-
# @option [String] :namespace Prefix used to namespace entries
|
28
|
-
# @option [Number] :pool_size (5) The number of threads in the pool
|
29
|
-
# @option [Number] :pool_timeout (5) How long before a thread times out
|
22
|
+
# @option options [Hash] :redis Options that will be passed to the redis connection
|
23
|
+
# @option options [Boolean] :compress (false) Enable or disable automatic compression
|
24
|
+
# @option options [Number] :compression_threshold (8k) Minimum string size for compression
|
25
|
+
# @option options [Number] :expires_in The number of seconds until an entry expires
|
26
|
+
# @option options [Boolean] :refresh (false) Automatically refresh key expiration
|
27
|
+
# @option options [Module] :marshal (Marshal) Module that responds to `dump` and `load`
|
28
|
+
# @option options [String] :namespace Prefix used to namespace entries
|
29
|
+
# @option options [Number] :pool_size (5) The number of threads in the pool
|
30
|
+
# @option options [Number] :pool_timeout (5) How long before a thread times out
|
30
31
|
#
|
31
32
|
# @example Create a new cache instance
|
32
33
|
# Readthis::Cache.new(namespace: 'cache',
|
@@ -47,14 +48,16 @@ module Readthis
|
|
47
48
|
@pool = ConnectionPool.new(pool_options(options)) do
|
48
49
|
Redis.new(options.fetch(:redis, {}))
|
49
50
|
end
|
51
|
+
|
52
|
+
@scripts = Readthis::Scripts.new
|
50
53
|
end
|
51
54
|
|
52
55
|
# Fetches data from the cache, using the given key. If there is data in
|
53
56
|
# the cache with the given key, then that data is returned. Otherwise, nil
|
54
57
|
# is returned.
|
55
58
|
#
|
56
|
-
# @param [String] Key for lookup
|
57
|
-
# @param [Hash] Optional overrides
|
59
|
+
# @param [String] key Key for lookup
|
60
|
+
# @param [Hash] options Optional overrides
|
58
61
|
#
|
59
62
|
# @example
|
60
63
|
#
|
@@ -76,8 +79,8 @@ module Readthis
|
|
76
79
|
# Writes data to the cache using the given key. Will overwrite whatever
|
77
80
|
# value is already stored at that key.
|
78
81
|
#
|
79
|
-
# @param [String] Key for lookup
|
80
|
-
# @param [Hash] Optional overrides
|
82
|
+
# @param [String] key Key for lookup
|
83
|
+
# @param [Hash] options Optional overrides
|
81
84
|
#
|
82
85
|
# @example
|
83
86
|
#
|
@@ -96,8 +99,8 @@ module Readthis
|
|
96
99
|
# Delete the value stored at the specified key. Returns `true` if
|
97
100
|
# anything was deleted, `false` otherwise.
|
98
101
|
#
|
99
|
-
# @
|
100
|
-
# @
|
102
|
+
# @param [String] key The key for lookup
|
103
|
+
# @param [Hash] options Optional overrides
|
101
104
|
#
|
102
105
|
# @example
|
103
106
|
#
|
@@ -121,10 +124,11 @@ module Readthis
|
|
121
124
|
# the block will be written to the cache under the given cache key, and
|
122
125
|
# that return value will be returned.
|
123
126
|
#
|
124
|
-
# @param [String] Key for lookup
|
125
|
-
# @param [Block] Optional block for generating the value when missing
|
127
|
+
# @param [String] key Key for lookup
|
126
128
|
# @param options [Hash] Optional overrides
|
127
129
|
# @option options [Boolean] :force Force a cache miss
|
130
|
+
# @yield [String] Gives a missing key to the block, which is used to
|
131
|
+
# generate the missing value
|
128
132
|
#
|
129
133
|
# @example Typical
|
130
134
|
#
|
@@ -137,6 +141,7 @@ module Readthis
|
|
137
141
|
# cache.fetch('city') do
|
138
142
|
# 'Duckburgh'
|
139
143
|
# end
|
144
|
+
#
|
140
145
|
# cache.fetch('city') # => "Duckburgh"
|
141
146
|
#
|
142
147
|
# @example Cache Miss
|
@@ -161,9 +166,9 @@ module Readthis
|
|
161
166
|
# If the key doesn't exist it will be initialized at 0. If the key exists
|
162
167
|
# but it isn't a Fixnum it will be initialized at 0.
|
163
168
|
#
|
164
|
-
# @param [String] Key for lookup
|
165
|
-
# @param [Fixnum] Value to increment by
|
166
|
-
# @param [Hash] Optional overrides
|
169
|
+
# @param [String] key Key for lookup
|
170
|
+
# @param [Fixnum] amount Value to increment by
|
171
|
+
# @param [Hash] options Optional overrides
|
167
172
|
#
|
168
173
|
# @example
|
169
174
|
#
|
@@ -182,9 +187,9 @@ module Readthis
|
|
182
187
|
# If the key doesn't exist it will be initialized at 0. If the key exists
|
183
188
|
# but it isn't a Fixnum it will be initialized at 0.
|
184
189
|
#
|
185
|
-
# @param [String] Key for lookup
|
186
|
-
# @param [Fixnum] Value to decrement by
|
187
|
-
# @param [Hash] Optional overrides
|
190
|
+
# @param [String] key Key for lookup
|
191
|
+
# @param [Fixnum] amount Value to decrement by
|
192
|
+
# @param [Hash] options Optional overrides
|
188
193
|
#
|
189
194
|
# @example
|
190
195
|
#
|
@@ -233,8 +238,8 @@ module Readthis
|
|
233
238
|
#
|
234
239
|
# This is a non-standard, but useful, cache method.
|
235
240
|
#
|
236
|
-
# @param [Hash] Key value hash to write
|
237
|
-
# @param [Hash] Optional overrides
|
241
|
+
# @param [Hash] hash Key value hash to write
|
242
|
+
# @param [Hash] options Optional overrides
|
238
243
|
#
|
239
244
|
# @example
|
240
245
|
#
|
@@ -291,8 +296,8 @@ module Readthis
|
|
291
296
|
|
292
297
|
# Returns `true` if the cache contains an entry for the given key.
|
293
298
|
#
|
294
|
-
# @param [String] Key for lookup
|
295
|
-
# @param [Hash] Optional overrides
|
299
|
+
# @param [String] key Key for lookup
|
300
|
+
# @param [Hash] options Optional overrides
|
296
301
|
#
|
297
302
|
# @example
|
298
303
|
#
|
@@ -308,11 +313,12 @@ module Readthis
|
|
308
313
|
# Clear the entire cache. This flushes the current database, no
|
309
314
|
# globbing is applied.
|
310
315
|
#
|
311
|
-
# @param [Hash] Options, only present for compatibility
|
316
|
+
# @param [Hash] _options Options, only present for compatibility
|
312
317
|
#
|
313
318
|
# @example
|
314
319
|
#
|
315
320
|
# cache.clear #=> 'OK'
|
321
|
+
#
|
316
322
|
def clear(_options = nil)
|
317
323
|
invoke(:clear, '*', &:flushdb)
|
318
324
|
end
|
@@ -322,11 +328,9 @@ module Readthis
|
|
322
328
|
def refresh_entity(keys, store, options)
|
323
329
|
return unless options[:refresh] && options[:expires_in]
|
324
330
|
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
end
|
329
|
-
end
|
331
|
+
expiration = coerce_expiration(options[:expires_in])
|
332
|
+
|
333
|
+
scripts.run('mexpire', store, keys, expiration)
|
330
334
|
end
|
331
335
|
|
332
336
|
def write_entity(key, value, store, options)
|
data/lib/readthis/entity.rb
CHANGED
@@ -1,13 +1,19 @@
|
|
1
1
|
require 'zlib'
|
2
2
|
|
3
3
|
module Readthis
|
4
|
+
# An instance of the Entity class is used to handle `load` and `dump`
|
5
|
+
# operations on cached values.
|
4
6
|
class Entity
|
7
|
+
# Unless they are overridden, these are the options used to load and unload
|
8
|
+
# every value.
|
5
9
|
DEFAULT_OPTIONS = {
|
6
10
|
compress: false,
|
7
11
|
marshal: Marshal,
|
8
12
|
threshold: 8 * 1024
|
9
13
|
}.freeze
|
10
14
|
|
15
|
+
# A hexidecimal compression flag. When it is present within the magic bit
|
16
|
+
# of an entity that entity is considered compressed.
|
11
17
|
COMPRESSED_FLAG = 0x8
|
12
18
|
|
13
19
|
# Creates a Readthis::Entity with default options. Each option can be
|
@@ -17,9 +23,12 @@ module Readthis
|
|
17
23
|
# automatically be used again when loading, regardless of how current
|
18
24
|
# options are set.
|
19
25
|
#
|
20
|
-
# @option [Boolean] :compress (false) Enable or disable automatic
|
21
|
-
#
|
22
|
-
# @option [
|
26
|
+
# @option [Boolean] :compress (false) Enable or disable automatic
|
27
|
+
# compression
|
28
|
+
# @option [Module] :marshal (Marshal) Any module that responds to `dump`
|
29
|
+
# and `load`
|
30
|
+
# @option [Number] :threshold (8k) The size a string must be for
|
31
|
+
# compression
|
23
32
|
#
|
24
33
|
def initialize(options = {})
|
25
34
|
@options = DEFAULT_OPTIONS.merge(options)
|
@@ -28,10 +37,13 @@ module Readthis
|
|
28
37
|
# Output a value prepared for cache storage. Passed options will override
|
29
38
|
# whatever has been specified for the instance.
|
30
39
|
#
|
31
|
-
# @param
|
32
|
-
# @option [Boolean] :compress Enable or disable automatic
|
33
|
-
#
|
34
|
-
# @option [
|
40
|
+
# @param [String] value String to dump
|
41
|
+
# @option options [Boolean] :compress Enable or disable automatic
|
42
|
+
# compression
|
43
|
+
# @option options [Module] :marshal Any module that responds to `dump` and
|
44
|
+
# `load`
|
45
|
+
# @option options [Number] :threshold The size a string must be for
|
46
|
+
# compression
|
35
47
|
# @return [String] The prepared, possibly compressed, string
|
36
48
|
#
|
37
49
|
# @example Dumping a value using defaults
|
@@ -54,7 +66,7 @@ module Readthis
|
|
54
66
|
|
55
67
|
# Parse a dumped value using the embedded options.
|
56
68
|
#
|
57
|
-
# @param
|
69
|
+
# @param [String] string Option embedded string to load
|
58
70
|
# @return [String] The original dumped string, restored
|
59
71
|
#
|
60
72
|
# @example
|
@@ -77,9 +89,9 @@ module Readthis
|
|
77
89
|
# Where there are four unused bits, 1 compression bit, and 3 bits for the
|
78
90
|
# serializer. This allows up to 8 different serializers for marshaling.
|
79
91
|
#
|
80
|
-
# @param [String] String to prefix with flags
|
81
|
-
# @param [Module] The marshal module to be used
|
82
|
-
# @param [Boolean] Flag determining whether the value is compressed
|
92
|
+
# @param [String] value String to prefix with flags
|
93
|
+
# @param [Module] marshal The marshal module to be used
|
94
|
+
# @param [Boolean] compress Flag determining whether the value is compressed
|
83
95
|
# @return [String] The original string with a single byte prefixed
|
84
96
|
#
|
85
97
|
# @example Compose an option embedded string
|
@@ -96,7 +108,7 @@ module Readthis
|
|
96
108
|
|
97
109
|
# Decompose an option embedded string into marshal, compression and value.
|
98
110
|
#
|
99
|
-
# @param [String] Option embedded string to
|
111
|
+
# @param [String] string Option embedded string to
|
100
112
|
# @return [Array<Module, Boolean, String>] An array comprised of the
|
101
113
|
# marshal, compression flag, and the base string.
|
102
114
|
#
|
data/lib/readthis/errors.rb
CHANGED
@@ -1,7 +1,22 @@
|
|
1
1
|
module Readthis
|
2
|
+
# This is the base error that all other specific errors inherit from,
|
3
|
+
# making it possible to rescue the `ReadthisError` superclass.
|
4
|
+
#
|
5
|
+
# This isn't raised by itself.
|
2
6
|
ReadthisError = Class.new(StandardError)
|
3
7
|
|
8
|
+
# Raised when attempting to modify the serializers after they have been
|
9
|
+
# frozen.
|
4
10
|
SerializersFrozenError = Class.new(ReadthisError)
|
11
|
+
|
12
|
+
# Raised when attempting to add a new serializer after the limit of 7 is
|
13
|
+
# reached.
|
5
14
|
SerializersLimitError = Class.new(ReadthisError)
|
15
|
+
|
16
|
+
# Raised when an unknown script is called.
|
17
|
+
UnknownCommandError = Class.new(ReadthisError)
|
18
|
+
|
19
|
+
# Raised when a serializer was specified, but hasn't been configured for
|
20
|
+
# usage.
|
6
21
|
UnknownSerializerError = Class.new(ReadthisError)
|
7
22
|
end
|
data/lib/readthis/expanders.rb
CHANGED
@@ -7,7 +7,10 @@ module Readthis
|
|
7
7
|
when key.is_a?(Array)
|
8
8
|
key.flat_map { |elem| expand_key(elem) }.join('/')
|
9
9
|
when key.is_a?(Hash)
|
10
|
-
key
|
10
|
+
key
|
11
|
+
.sort_by { |hkey, _| hkey.to_s }
|
12
|
+
.map { |hkey, val| "#{hkey}=#{val}" }
|
13
|
+
.join('/')
|
11
14
|
when key.respond_to?(:to_param)
|
12
15
|
key.to_param
|
13
16
|
else
|
data/lib/readthis/passthrough.rb
CHANGED
@@ -0,0 +1,50 @@
|
|
1
|
+
module Readthis
|
2
|
+
# The `Scripts` class is used to conveniently execute lua scripts. The first
|
3
|
+
# time a command is run it is stored on the server and subsequently referred
|
4
|
+
# to by its SHA. Each instance tracks SHAs separately, they are not global.
|
5
|
+
class Scripts
|
6
|
+
attr_reader :loaded
|
7
|
+
|
8
|
+
# Creates a new Readthis::Scripts instance.
|
9
|
+
def initialize
|
10
|
+
@loaded = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
# Run a named lua script with the provided keys and arguments.
|
14
|
+
#
|
15
|
+
# @param [String] command The script to run, without a `.lua` extension
|
16
|
+
# @param [#Store] store A Redis client for storing and evaluating the script
|
17
|
+
# @param [Array] keys One or more keys to pass to the command
|
18
|
+
# @param [Array] args One or more args to pass to the command
|
19
|
+
#
|
20
|
+
# @return [Any] The Redis converted value returned on the script
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
#
|
24
|
+
# scripts.run('mexpire', store, %w[a b c], 1) # => 'OK'
|
25
|
+
#
|
26
|
+
def run(command, store, keys, args = [])
|
27
|
+
store.evalsha(
|
28
|
+
sha(command, store),
|
29
|
+
Array(keys),
|
30
|
+
Array(args)
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def sha(command, store)
|
37
|
+
loaded[command] ||= load_script!(command, store)
|
38
|
+
end
|
39
|
+
|
40
|
+
def load_script!(command, store)
|
41
|
+
path = File.join('script', "#{command}.lua")
|
42
|
+
|
43
|
+
File.open(path) do |file|
|
44
|
+
loaded[command] = store.script(:load, file.read)
|
45
|
+
end
|
46
|
+
rescue Errno::ENOENT
|
47
|
+
raise Readthis::UnknownCommandError, "unknown command '#{command}'"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/readthis/serializers.rb
CHANGED
@@ -4,12 +4,16 @@ require 'readthis/passthrough'
|
|
4
4
|
|
5
5
|
module Readthis
|
6
6
|
class Serializers
|
7
|
+
# Defines the default set of three serializers: Marshal, Passthrough, and
|
8
|
+
# JSON. With a hard limit of 7 that leaves 4 additional slots.
|
7
9
|
BASE_SERIALIZERS = {
|
8
10
|
Marshal => 0x1,
|
9
11
|
Passthrough => 0x2,
|
10
12
|
JSON => 0x3
|
11
13
|
}.freeze
|
12
14
|
|
15
|
+
# The hard serializer limit, based on the number of possible values within
|
16
|
+
# a single 3bit integer.
|
13
17
|
SERIALIZER_LIMIT = 7
|
14
18
|
|
15
19
|
attr_reader :serializers, :inverted
|
@@ -25,7 +29,7 @@ module Readthis
|
|
25
29
|
# any single application be configured for any single application. This
|
26
30
|
# limit is based on the number of bytes available in the option flag.
|
27
31
|
#
|
28
|
-
# @param [Module] Any object that responds to `dump` and `load`
|
32
|
+
# @param [Module] serializer Any object that responds to `dump` and `load`
|
29
33
|
# @return [self] Returns itself for possible chaining
|
30
34
|
#
|
31
35
|
# @example
|
@@ -37,7 +41,7 @@ module Readthis
|
|
37
41
|
case
|
38
42
|
when serializers.frozen?
|
39
43
|
raise SerializersFrozenError
|
40
|
-
when serializers.length
|
44
|
+
when serializers.length >= SERIALIZER_LIMIT
|
41
45
|
raise SerializersLimitError
|
42
46
|
else
|
43
47
|
@serializers[serializer] = flags.max.succ
|
@@ -63,7 +67,7 @@ module Readthis
|
|
63
67
|
|
64
68
|
# Find a flag for a serializer object.
|
65
69
|
#
|
66
|
-
# @param [Object] Look up a flag by object
|
70
|
+
# @param [Object] serializer Look up a flag by object
|
67
71
|
# @return [Number] Corresponding flag for the serializer object
|
68
72
|
# @raise [UnknownSerializerError] Indicates that a serializer was
|
69
73
|
# specified, but hasn't been configured for usage.
|
@@ -84,7 +88,7 @@ module Readthis
|
|
84
88
|
|
85
89
|
# Find a serializer object by flag value.
|
86
90
|
#
|
87
|
-
# @param [Number]
|
91
|
+
# @param [Number] flag Integer to look up the serializer object by
|
88
92
|
# @return [Module] The serializer object
|
89
93
|
#
|
90
94
|
# @example
|
@@ -92,7 +96,7 @@ module Readthis
|
|
92
96
|
# serializers.rassoc(1) #=> Marshal
|
93
97
|
#
|
94
98
|
def rassoc(flag)
|
95
|
-
inverted[flag &
|
99
|
+
inverted[flag & SERIALIZER_LIMIT]
|
96
100
|
end
|
97
101
|
|
98
102
|
# @private
|
data/lib/readthis/version.rb
CHANGED
data/lib/readthis.rb
CHANGED
@@ -7,7 +7,7 @@ module Readthis
|
|
7
7
|
# The current, global, instance of serializers that is used by all cache
|
8
8
|
# instances.
|
9
9
|
#
|
10
|
-
# @
|
10
|
+
# @return [Readthis::Serializers] An cached Serializers instance
|
11
11
|
#
|
12
12
|
# @see readthis/serializers
|
13
13
|
#
|
@@ -18,7 +18,7 @@ module Readthis
|
|
18
18
|
# Indicates whether connection error tolerance is enabled. With tolerance
|
19
19
|
# enabled every operation will return a `nil` value.
|
20
20
|
#
|
21
|
-
# @
|
21
|
+
# @return [Boolean] True for enabled, false for disabled
|
22
22
|
#
|
23
23
|
def fault_tolerant?
|
24
24
|
@fault_tolerant
|
@@ -26,7 +26,7 @@ module Readthis
|
|
26
26
|
|
27
27
|
# Toggle fault tolerance for connection errors.
|
28
28
|
#
|
29
|
-
# @param [Boolean] The new value for fault tolerance
|
29
|
+
# @param [Boolean] value The new value for fault tolerance
|
30
30
|
#
|
31
31
|
def fault_tolerant=(value)
|
32
32
|
@fault_tolerant = value
|
data/script/mexpire.lua
ADDED
data/spec/readthis/cache_spec.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'readthis'
|
2
1
|
require 'matchers/redis_matchers'
|
3
2
|
|
4
3
|
RSpec.describe Readthis::Cache do
|
@@ -173,6 +172,12 @@ RSpec.describe Readthis::Cache do
|
|
173
172
|
expect(cache.read('missing-key')).to eq(value)
|
174
173
|
end
|
175
174
|
|
175
|
+
it 'returns computed value when using passthrough marshalling' do
|
176
|
+
cache = Readthis::Cache.new(marshal: Readthis::Passthrough)
|
177
|
+
result = cache.fetch('missing-key') { 'value for you' }
|
178
|
+
expect(result).to eq('value for you')
|
179
|
+
end
|
180
|
+
|
176
181
|
it 'does not set for a missing key without a block' do
|
177
182
|
expect(cache.fetch('missing-key')).to be_nil
|
178
183
|
end
|
@@ -1,17 +1,16 @@
|
|
1
|
-
require 'readthis/passthrough'
|
2
|
-
|
3
1
|
RSpec.describe Readthis::Passthrough do
|
2
|
+
let(:value) { 'skywalker' }
|
3
|
+
|
4
4
|
describe '.load' do
|
5
5
|
it 'passes through the provided value' do
|
6
|
-
value = Object.new
|
7
6
|
expect(Readthis::Passthrough.load(value)).to eq(value)
|
8
7
|
end
|
9
8
|
end
|
10
9
|
|
11
10
|
describe '.dump' do
|
12
11
|
it 'passes through the provided value' do
|
13
|
-
value = Object.new
|
14
12
|
expect(Readthis::Passthrough.dump(value)).to eq(value)
|
13
|
+
expect(Readthis::Passthrough.dump(value)).not_to be(value)
|
15
14
|
end
|
16
15
|
end
|
17
16
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
RSpec.describe Readthis::Scripts do
|
2
|
+
let(:scripts) { Readthis::Scripts.new }
|
3
|
+
|
4
|
+
describe '#run' do
|
5
|
+
it 'raises an error with an unknown command' do
|
6
|
+
expect do
|
7
|
+
scripts.run('unknown', nil, [])
|
8
|
+
end.to raise_error(Readthis::UnknownCommandError)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'runs the script command with a single key' do
|
12
|
+
store = Redis.new
|
13
|
+
|
14
|
+
store.set('alpha', 'content')
|
15
|
+
scripts.run('mexpire', store, 'alpha', 1)
|
16
|
+
|
17
|
+
expect(store.ttl('alpha')).to eq(1)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'runs the script command with multiple keys' do
|
21
|
+
store = Redis.new
|
22
|
+
|
23
|
+
store.set('beta', 'content')
|
24
|
+
store.set('gamma', 'content')
|
25
|
+
scripts.run('mexpire', store, %w[beta gamma], 1)
|
26
|
+
|
27
|
+
expect(store.ttl('beta')).to eq(1)
|
28
|
+
expect(store.ttl('gamma')).to eq(1)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'readthis/serializers'
|
2
|
-
|
3
1
|
RSpec.describe Readthis::Serializers do
|
4
2
|
CustomSerializer = Class.new
|
5
3
|
AnotherSerializer = Class.new
|
@@ -24,9 +22,9 @@ RSpec.describe Readthis::Serializers do
|
|
24
22
|
|
25
23
|
it 'prevents more than seven serializers' do
|
26
24
|
serializers = Readthis::Serializers.new
|
27
|
-
|
25
|
+
serializers << Class.new until serializers.flags.length >= 7
|
28
26
|
expect do
|
29
|
-
|
27
|
+
serializers << Class.new
|
30
28
|
end.to raise_error(Readthis::SerializersLimitError)
|
31
29
|
end
|
32
30
|
end
|
@@ -48,18 +46,29 @@ RSpec.describe Readthis::Serializers do
|
|
48
46
|
end
|
49
47
|
|
50
48
|
describe '#rassoc' do
|
51
|
-
|
52
|
-
serializers = Readthis::Serializers.new
|
49
|
+
let(:serializers) { Readthis::Serializers.new }
|
53
50
|
|
51
|
+
it 'inverts the current set of serializers' do
|
54
52
|
expect(serializers.rassoc(1)).to eq(Marshal)
|
55
53
|
end
|
56
54
|
|
57
55
|
it 'returns custom serializers' do
|
58
|
-
serializers = Readthis::Serializers.new
|
59
56
|
serializers << CustomSerializer
|
60
|
-
|
61
57
|
expect(serializers.rassoc(4)).to eq(CustomSerializer)
|
62
58
|
end
|
59
|
+
|
60
|
+
it 'inverts default serializers after adding custom one' do
|
61
|
+
serializers << CustomSerializer
|
62
|
+
expect(serializers.rassoc(1)).to eq(Marshal)
|
63
|
+
expect(serializers.rassoc(3)).to eq(JSON)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'takes into account only first 3 bytes of passed integer' do
|
67
|
+
expect(serializers.rassoc(1)).to eq(Marshal)
|
68
|
+
expect(serializers.rassoc(11)).to eq(JSON)
|
69
|
+
serializers << CustomSerializer
|
70
|
+
expect(serializers.rassoc(12)).to eq(CustomSerializer)
|
71
|
+
end
|
63
72
|
end
|
64
73
|
|
65
74
|
describe '#freeze!' do
|
data/spec/readthis_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: readthis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Parker Selbert
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -123,13 +123,16 @@ files:
|
|
123
123
|
- lib/readthis/errors.rb
|
124
124
|
- lib/readthis/expanders.rb
|
125
125
|
- lib/readthis/passthrough.rb
|
126
|
+
- lib/readthis/scripts.rb
|
126
127
|
- lib/readthis/serializers.rb
|
127
128
|
- lib/readthis/version.rb
|
129
|
+
- script/mexpire.lua
|
128
130
|
- spec/matchers/redis_matchers.rb
|
129
131
|
- spec/readthis/cache_spec.rb
|
130
132
|
- spec/readthis/entity_spec.rb
|
131
133
|
- spec/readthis/expanders_spec.rb
|
132
134
|
- spec/readthis/passthrough_spec.rb
|
135
|
+
- spec/readthis/scripts_spec.rb
|
133
136
|
- spec/readthis/serializers_spec.rb
|
134
137
|
- spec/readthis_spec.rb
|
135
138
|
- spec/spec_helper.rb
|
@@ -163,6 +166,8 @@ test_files:
|
|
163
166
|
- spec/readthis/entity_spec.rb
|
164
167
|
- spec/readthis/expanders_spec.rb
|
165
168
|
- spec/readthis/passthrough_spec.rb
|
169
|
+
- spec/readthis/scripts_spec.rb
|
166
170
|
- spec/readthis/serializers_spec.rb
|
167
171
|
- spec/readthis_spec.rb
|
168
172
|
- spec/spec_helper.rb
|
173
|
+
has_rdoc:
|