redis-script_manager 0.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e5a3988633cfd5315a4591a70edc873c902fe829
4
+ data.tar.gz: 9e279ed9af52df46d347c69a7f51ce21bf3cfc47
5
+ SHA512:
6
+ metadata.gz: 4408f0dd1575e24f23cd5888d44ce7d539d47955cd9c19100237e886ead48b0b4fd49d3d6f84e79478c307e47d0ee69e5d77ca468029704b18bc30357adddf51
7
+ data.tar.gz: 754d3250762ec2fbbd0e058b403ba0797aa4d1899a0ba1bc04d79430574ed7d71e882242fbd81f39134a43b1f6b0aa88b58ae7b883e23c175cb3cb87fc54e307
data/.gitignore ADDED
@@ -0,0 +1,50 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ # .ruby-version
47
+ # .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.1.6
5
+ before_install: gem install bundler -v 1.14.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in redis-script_manager.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,27 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ redis-script_manager (0.0.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ minitest (5.10.3)
10
+ rake (10.5.0)
11
+ redis (3.3.3)
12
+ redis-namespace (1.5.3)
13
+ redis (~> 3.0, >= 3.0.4)
14
+
15
+ PLATFORMS
16
+ ruby
17
+
18
+ DEPENDENCIES
19
+ bundler (~> 1.14)
20
+ minitest (~> 5.0)
21
+ rake (~> 10.0)
22
+ redis (~> 3.2)
23
+ redis-namespace (~> 1.5)
24
+ redis-script_manager!
25
+
26
+ BUNDLED WITH
27
+ 1.15.3
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 ProsperWorks
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,125 @@
1
+ # Redis::ScriptManager
2
+
3
+ Redis::ScriptManager executes your Lua scripts in your Redis
4
+ infrastructure while managing trade-offs between bandwidth and
5
+ statefulness.
6
+
7
+ ## Other Packages With Related Functionality
8
+
9
+ ### resque-scheduler
10
+
11
+ https://github.com/resque/resque-scheduler
12
+
13
+ Resque::Scheduler::Lock::Resiliant manages its scripts with
14
+ load-on-init and EVALSHA-else-SCRIPT-LOAD-and-re-EVALSHA.
15
+
16
+ This is robust if there are no SCRIPT FLUSH or no pipelines, but it
17
+ will fail if a SCRIPT FLUSH can happen after init, then we run in a
18
+ pipeline.
19
+
20
+ The Lua scripts in resque-scheduler are only a few 100s of bytes in
21
+ size, so there is little to be gained by avoiding simply using EVAL.
22
+
23
+ Warning: resque-scheduler embeds "#{timeout}" in its Lua scripts. One
24
+ is unlikely to change resque-scheduler lock timeouts frequently, but
25
+ if so it could be possible to fill the Redis script cache with tons of
26
+ abandoned scripts.
27
+
28
+ ### wolverine
29
+
30
+ https://github.com/Shopify/wolverine
31
+ http://shopify.github.io/wolverine/
32
+
33
+ Wolverine does load-on-init and EVALSHA-only. Assuming you have only
34
+ one Redis connection and SCRIPT FLUSH is never called, this is fine
35
+ even in a pipeline.
36
+
37
+ If you juggle multiple Redis connections or are worried about
38
+ inconsistent script cache contents, Wolverine might have some gaps.
39
+
40
+ Wolverine also has nice support for keeping your Lua scripts in a
41
+ repository of related .lua files, with support for common code
42
+ folding.
43
+
44
+ ### redis-lua
45
+
46
+ https://github.com/chanks/redis-lua
47
+
48
+ Redis-lua does EVALSHA-else-SCRIPT-LOAD-and-re-EVALSHA when not in a
49
+ pipeline, simple EVAL otherwise.
50
+
51
+ This is great: this is always correct regardless of how many Redises
52
+ you are talking to, and calls outside of a pipeline will tend toward
53
+ minimal bandwith as the script cache gets warmed up.
54
+
55
+ However, if most of your scripting is done within a pipeline,
56
+ bandwidth use will stay high.
57
+
58
+ Early iterations of redis-script_manager were inspired by redis-lua.
59
+
60
+ ### redis-rb-scripting
61
+
62
+ https://github.com/codekitchen/redis-rb-scripting
63
+
64
+ redis-rb-scripting does load-on-init plus EVALSHA-else-EVAL. It is
65
+ correct when the script cache is inconsistent but does not tend to
66
+ repopulate the cache in these cases.
67
+
68
+ redis-rb-scripting has no special provision for pipelines. Called in
69
+ a pipeline it will fail to recover from a cold cache.
70
+
71
+ Like wolverine, redis-rb-scripting also supports a repository of .lua
72
+ files, but without the common code folding.
73
+
74
+ ### led
75
+
76
+ https://github.com/ciconia/led
77
+
78
+ Like redis-rb-scripting, led does load-on-init plus EVALSHA-else-EVAL.
79
+ It is correct when the script cache is inconsistent but does not tend
80
+ to repopulate the cache in these cases. It has no special provision
81
+ for pipelines. Called in a pipeline it will fail to recover from a
82
+ cold cache.
83
+
84
+ Like wolverine, redis-rb-scripting also supports a repository of .lua
85
+ files with common code folding.
86
+
87
+
88
+ ## Installation
89
+
90
+ Add this line to your application's Gemfile:
91
+
92
+ ```ruby
93
+ gem 'redis-script_manager'
94
+ ```
95
+
96
+ And then execute:
97
+
98
+ $ bundle
99
+
100
+ Or install it yourself as:
101
+
102
+ $ gem install redis-script_manager
103
+
104
+ ## Usage
105
+
106
+ TODO: Write usage instructions here
107
+
108
+ ## Development
109
+
110
+ After checking out the repo, run `bin/setup` to install
111
+ dependencies. Then, run `rake test` to run the tests. You can also run
112
+ `bin/console` for an interactive prompt that will allow you to
113
+ experiment.
114
+
115
+ To install this gem onto your local machine, run `bundle exec rake
116
+ install`. To release a new version, update the version number in
117
+ `version.rb`, and then run `bundle exec rake release`, which will
118
+ create a git tag for the version, push git commits and tags, and push
119
+ the `.gem` file to [rubygems.org](https://rubygems.org).
120
+
121
+ ## Contributing
122
+
123
+ Bug reports and pull requests are welcome on GitHub at
124
+ https://github.com/[USERNAME]/redis-script_manager.
125
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "redis/script_manager"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,334 @@
1
+ require "redis/script_manager/version"
2
+
3
+ class Redis
4
+ class ScriptManager
5
+
6
+ # TODO: rubocop
7
+
8
+ # TODO: rdoc
9
+
10
+ # Efficiently evaluates a Lua script on Redis.
11
+ #
12
+ # Makes a best effort to moderate bandwidth by leveraging EVALSHA
13
+ # and managing the SCRIPT LOAD state.
14
+ #
15
+ # @param redis a Redis to call, must respond to :eval, :evalsha,
16
+ # and :script
17
+ #
18
+ # @param lua a String, the Lua script to execute on redis
19
+ #
20
+ # @param keys a list of String, the keys which will bind to the KEYS
21
+ # list in the lua script.
22
+ #
23
+ # @param args a list of arguments which will bind to ARGV list in
24
+ # the lua script.
25
+ #
26
+ # @return the return result of evaluating lua against keys and args
27
+ # on redis
28
+ #
29
+ # TODO: Should this just monkey-patch over Redis.eval?
30
+ #
31
+ def self.eval_gently(redis,lua,keys=[],args=[])
32
+ [:eval,:evalsha,:script,:client].each do |method|
33
+ if !redis.respond_to?(method) || !redis.respond_to?(:script)
34
+ raise ArgumentError, "bogus redis #{redis}, no #{method}"
35
+ end
36
+ end
37
+ if !lua.is_a?(String)
38
+ raise ArgumentError, "bogus lua #{lua}"
39
+ end
40
+ if !keys.is_a?(Array)
41
+ raise ArgumentError, "bogus keys #{keys}: non-array"
42
+ end
43
+ keys_classes = keys.map(&:class).uniq
44
+ if [] != keys_classes - [String,Symbol]
45
+ raise ArgumentError, "bogus keys #{keys}: bad types in #{keys_classes}"
46
+ end
47
+ if !args.is_a?(Array)
48
+ raise ArgumentError, "bogus args #{args}"
49
+ end
50
+ if keys.size < 1
51
+ raise ArgumentError, 'Twemproxy intolerant of 0 keys in EVAL or EVALSHA'
52
+ end
53
+ #
54
+ # Per http://redis.io/commands/eval:
55
+ #
56
+ # Redis does not need to recompile the script every time as it
57
+ # uses an internal caching mechanism, however paying the cost of
58
+ # the additional bandwidth may not be optimal in many contexts."
59
+ #
60
+ # So, where the bandwidth imposed by uploading a short script is
61
+ # small, we will just use EVAL. Also, in MONITOR streams it can
62
+ # be nice to see the Lua instead of a bunch of noisy shas.
63
+ #
64
+ # However, where the script is long we try to conserve bandwidth
65
+ # by trying EVALSHA first. In case our script has never been
66
+ # uploaded before, or if the Redis suffered a FLUSHDB or SCRIPT
67
+ # FLUSH, we catch NOSCRIPT error, recover with SCRIPT LOAD, and
68
+ # repeat the EVALSHA.
69
+ #
70
+ # Caveat: if all of this is wrapped in a Redis pipeline, then the
71
+ # first EVALSHA returns a Redis::Future, not a result. We won't
72
+ # know whether it throws an error until after the pipeline - and
73
+ # after we've committed to the rest of our stream of commands.
74
+ # Thus, we can't recover from a NOSCRIPT error.
75
+ #
76
+ # To be safe in this pipelined-but-not-in-script-database edge
77
+ # case, we stick with simple EVAL when we detect we are running
78
+ # within a pipeline.
79
+ #
80
+ if configuration.do_minify_lua
81
+ lua = self.minify_lua(lua)
82
+ end
83
+ if lua.size < configuration.max_tiny_lua
84
+ _statsd_increment("eval")
85
+ return redis.eval(lua,keys,args)
86
+ end
87
+ if configuration.do_preload
88
+ #
89
+ # I tested RLEC in ali-staging with this script:
90
+ #
91
+ # sha = Redis.current.script(:load,'return redis.call("get",KEYS[1])')
92
+ # 100.times.map { |n| "foo-#{n}" }.each do |key|
93
+ # set = Redis.current.set(key,key)
94
+ # get = Redis.current.evalsha(sha,[key])
95
+ # puts "%7s %7s %7s" % [key,get,set]
96
+ # end
97
+ #
98
+ # Sure enough, all 100 EVALSHA worked. Since ali-staging is a
99
+ # full-weight sharded RLEC, this tells me that SCRIPT LOAD
100
+ # propagates to all Redis shards in RLEC.
101
+ #
102
+ # Thus, we can trust that any script need only be sent down a
103
+ # particular Redis connection once. Thereafter we can assume
104
+ # EVALSHA will work.
105
+ #
106
+ # I do not know if the same thing will happen in Redis Cluster,
107
+ # and I am just about certain that the more primitive
108
+ # Twemproxy-over-array-of-plain-Redis will *not* propagate
109
+ # SCRIPT this way.
110
+ #
111
+ # Here is an twemproxy issue which tracks this question
112
+ # https://github.com/twitter/twemproxy/issues/68.
113
+ #
114
+ # This implementation is meant to transmit each script to each
115
+ # Redis no more than once per process, and thereafter be
116
+ # pure-EVALSHA.
117
+ #
118
+ sha = Digest::SHA1.hexdigest(lua)
119
+ sha_connection_key = [redis.object_id,sha]
120
+ if !@@preloaded_shas.include?(sha_connection_key)
121
+ _statsd_increment("preloaded_shas.cache_miss")
122
+ new_sha = redis.script(:load,lua)
123
+ if !new_sha.is_a?(Redis::Future)
124
+ if sha != new_sha
125
+ raise RuntimeError, "mismatch #{sha} vs #{new_sha} for lua #{lua}"
126
+ end
127
+ end
128
+ @@preloaded_shas << sha_connection_key
129
+ else
130
+ _statsd_increment("preloaded_shas.cache_hit")
131
+ end
132
+ result = redis.evalsha(sha,keys,args)
133
+ if configuration.preload_cache_size < @@preloaded_shas.size
134
+ #
135
+ # To defend against unbound cache size, at a predetermined
136
+ # limit throw away half of them.
137
+ #
138
+ # It is benign to re-load a script, just a performance blip.
139
+ #
140
+ # If these caches are running away in size, we have a worse
141
+ # time: redis.info.used_memory_lua could be growing without
142
+ # bound.
143
+ #
144
+ _statsd_increment("preloaded_shas.cache_purge")
145
+ num_to_keep = @@preloaded_shas.size / 2
146
+ @@preloaded_shas = @@preloaded_shas.to_a.sample(num_to_keep)
147
+ end
148
+ cache_size = @@preloaded_shas.size
149
+ _statsd_timing("preloaded_shas.cache_size",cache_size)
150
+ return result
151
+ end
152
+ in_pipeline = redis.client.is_a?(Redis::Pipeline) # thanks @marshall
153
+ if in_pipeline
154
+ _statsd_increment("pipeline_eval")
155
+ return redis.eval(lua,keys,args)
156
+ end
157
+ sha = Digest::SHA1.hexdigest(lua)
158
+ begin
159
+ _statsd_increment("evalsha1")
160
+ result = redis.evalsha(sha,keys,args)
161
+ if result.is_a?(Redis::Future)
162
+ #
163
+ # We should have detected this above where we checked whether
164
+ # redis.client was a pipeline.
165
+ #
166
+ raise "internal error: unexpected Redis::Future from evalsha"
167
+ end
168
+ result
169
+ rescue Redis::CommandError => ex
170
+ if nil != ex.to_s.index('NOSCRIPT') # some vulerability to change in msg
171
+ _statsd_increment("script_load")
172
+ new_sha = redis.script(:load,lua)
173
+ if sha != new_sha
174
+ raise RuntimeError, "mismatch #{sha} vs #{new_sha} for lua #{lua}"
175
+ end
176
+ _statsd_increment("evalsha2")
177
+ return redis.evalsha(sha,keys,args)
178
+ end
179
+ raise ex
180
+ end
181
+ end
182
+
183
+ @@preloaded_shas = Set[] # [redis.object_id,sha(lua)] which have been loaded
184
+
185
+ def self.purge_preloaded_shas # for test, clean state
186
+ @@preloaded_shas = Set[]
187
+ end
188
+
189
+ # To save bandwidth, minify the Lua code.
190
+ #
191
+ def self.minify_lua(lua)
192
+ lua
193
+ .split("\n")
194
+ .map { |l| l.gsub(/\s*--[^'"]*$/,'').strip } # rest-of-line comments
195
+ .reject { |l| /^\s*$/ =~ l } # blank lines
196
+ .join("\n")
197
+ end
198
+
199
+ # Reports a single count on the requested metric to statsd (if
200
+ # any).
201
+ #
202
+ # @param metric String
203
+ #
204
+ def self._statsd_increment(metric)
205
+ if configuration.statsd
206
+ configuration.statsd.increment(configuration.stats_prefix+metric)
207
+ end
208
+ end
209
+
210
+ # Reports a timing on the requested metric to statsd (if any).
211
+ #
212
+ # @param metric String
213
+ #
214
+ def self._statsd_timing(metric,timing)
215
+ if configuration.statsd
216
+ configuration.statsd.timing(configuration.stats_prefix+metric,timing)
217
+ end
218
+ end
219
+
220
+ # @returns the current Redis::ScriptManager::Configuration.
221
+ #
222
+ def self.configuration
223
+ @configuration ||= Configuration.new
224
+ end
225
+
226
+ # Sets the current Redis::ScriptManager::Configuration.
227
+ #
228
+ def self.configuration=(configuration)
229
+ @configuration = configuration
230
+ end
231
+
232
+ # Yields the current Redis::ScriptManager::Configuration, supports
233
+ # the typical gem configuration pattern:
234
+ #
235
+ # Redis::ScriptManager.configure do |config|
236
+ # config.statsd = $statsd
237
+ # config.stats_prefix = 'foo'
238
+ # config.minify_lua = true
239
+ # config.max_tiny_lua = 1235
240
+ # config.preload_shas = true
241
+ # config.preload_cache_size = 10
242
+ # end
243
+ #
244
+ def self.configure
245
+ yield configuration
246
+ end
247
+
248
+ class Configuration
249
+
250
+ # Defaults to nil. If non-nil, lots of stats will be tracked via
251
+ # statsd.increment and statsd.timing.
252
+ #
253
+ def statsd
254
+ @statsd || nil
255
+ end
256
+ def statsd=(statsd)
257
+ if statsd && !statsd.respond_to?(:increment)
258
+ raise ArgumentError, "bogus statsd A #{statsd}"
259
+ end
260
+ if statsd && !statsd.respond_to?(:timing)
261
+ raise ArgumentError, "bogus statsd B #{statsd}"
262
+ end
263
+ @statsd = statsd
264
+ end
265
+
266
+ # Defaults to ''.
267
+ #
268
+ # Prefixed onto all metrics.
269
+ #
270
+ def stats_prefix
271
+ @stats_prefix || ''
272
+ end
273
+ def stats_prefix=(stats_prefix)
274
+ if stats_prefix && !stats_prefix.is_a?(String)
275
+ raise ArgumentError, "bogus stats_prefix"
276
+ end
277
+ @stats_prefix = stats_prefix || ''
278
+ end
279
+
280
+ # Defaults to false.
281
+ #
282
+ # If true, all Lua is minified conservatively to save bandwidth
283
+ # before any other logic or evaluation.
284
+ #
285
+ def do_minify_lua
286
+ @do_minify_lua || false
287
+ end
288
+ def do_minify_lua=(do_minify_lua)
289
+ @do_minify_lua = [true,'true'].include?(do_minify_lua)
290
+ end
291
+
292
+ # Scripts shorter than max_tiny_lua are always EVALed.
293
+ #
294
+ # We skip all logic regarding EVALSHA, extra round-trips for
295
+ # SCRIPT LOAD, etc.
296
+ #
297
+ # Defaults to 512. Integers and Strings which convert to Integers OK.
298
+ #
299
+ def max_tiny_lua
300
+ @max_tiny_lua || 512
301
+ end
302
+ def max_tiny_lua=(max_tiny_lua)
303
+ @max_tiny_lua = max_tiny_lua.to_i
304
+ end
305
+
306
+ # Defaults to false.
307
+ #
308
+ # If true, shas are preloaded for each Redis connection (which
309
+ # make safe to use EVALSHA even in pipelines).
310
+ #
311
+ def do_preload
312
+ @do_preload || false
313
+ end
314
+ def do_preload=(do_preload)
315
+ @do_preload = [true,'true'].include?(do_preload)
316
+ end
317
+
318
+ # The cache of shas which have been preloaded is not allowed to
319
+ # grow larger than this value.
320
+ #
321
+ # Defaults to 1000.
322
+ #
323
+ def preload_cache_size
324
+ @preload_cache_size || 1000
325
+ end
326
+ def preload_cache_size=(preload_cache_size)
327
+ @preload_cache_size = preload_cache_size.to_i
328
+ end
329
+
330
+ end
331
+
332
+ end
333
+
334
+ end
@@ -0,0 +1,17 @@
1
+ class Redis
2
+ class ScriptManager
3
+ #
4
+ # Version plan:
5
+ #
6
+ # 0.0.1 - still in Prosperworks/ALI/vendor/gems/redis-script_manager
7
+ #
8
+ # 0.0.2 - broke out into Prosperworks/redis-script_manager
9
+ #
10
+ # 0.1.0 - big README.md and Rdoc update, open repo
11
+ #
12
+ # 0.2.0 - solicit and incorporate initial feedback from select
13
+ # beta external users
14
+ #
15
+ VERSION = "0.0.2" # broken into standalone repo, not polished
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'redis/script_manager/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+
7
+ spec.name = "redis-script_manager"
8
+ spec.version = Redis::ScriptManager::VERSION
9
+ spec.platform = Gem::Platform::RUBY
10
+
11
+ spec.authors = ["jhwillett"]
12
+ spec.email = ["jhw@prosperworks.com"]
13
+
14
+ spec.summary = 'Manage Lua script execution in Redis'
15
+ spec.homepage = 'https://github.com/ProsperWorks/redis-script_manager'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.14'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'minitest', '~> 5.0'
27
+ spec.add_development_dependency 'redis', '~> 3.2'
28
+ spec.add_development_dependency 'redis-namespace', '~> 1.5'
29
+
30
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: redis-script_manager
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - jhwillett
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-08-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.14'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: redis
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: redis-namespace
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.5'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.5'
83
+ description:
84
+ email:
85
+ - jhw@prosperworks.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".travis.yml"
92
+ - Gemfile
93
+ - Gemfile.lock
94
+ - LICENSE
95
+ - README.md
96
+ - Rakefile
97
+ - bin/console
98
+ - bin/setup
99
+ - lib/redis/script_manager.rb
100
+ - lib/redis/script_manager/version.rb
101
+ - redis-script_manager.gemspec
102
+ homepage: https://github.com/ProsperWorks/redis-script_manager
103
+ licenses: []
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.4.8
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: Manage Lua script execution in Redis
125
+ test_files: []