readthis 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://travis-ci.org/sorentwo/readthis.svg?branch=master)](https://travis-ci.org/sorentwo/readthis)
|
3
3
|
[![Code Climate](https://codeclimate.com/github/sorentwo/readthis/badges/gpa.svg)](https://codeclimate.com/github/sorentwo/readthis)
|
4
4
|
[![Coverage Status](https://coveralls.io/repos/sorentwo/readthis/badge.svg?branch=master&service=github)](https://coveralls.io/github/sorentwo/readthis?branch=master)
|
5
|
+
[![Inline Docs](http://inch-ci.org/github/sorentwo/readthis.svg?branch=master)](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:
|