memcached_store 0.12.7 → 0.12.8
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/.travis.yml +2 -0
- data/Gemfile +7 -1
- data/lib/active_support/cache/memcached_snappy_store.rb +5 -0
- data/lib/active_support/cache/memcached_store.rb +22 -0
- data/lib/memcached_store/memcached_safety.rb +20 -0
- data/lib/memcached_store/version.rb +1 -1
- data/memcached_store.gemspec +0 -4
- data/shipit.rubygems.yml +4 -1
- data/test/test_helper.rb +14 -0
- data/test/test_memcached_safety.rb +5 -0
- data/test/test_memcached_store.rb +214 -16
- metadata +3 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e458052cfc2aac92c629b37e02fc7ae66077dcd
|
4
|
+
data.tar.gz: af048ce101065d5bc3463a9e118b6c3fb45c7763
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 376570dd86abe4ca47cff7cb74aa934c7b26dac30ad24eeab5ee02b8310a24d9866d8c92ba2c85364c9c7bec426fe842e282b65d84742f2ba371db2cef478254
|
7
|
+
data.tar.gz: 8d958e238be593341eb041916ee4b47648a841ef3c87f45a3ebeeb1a2bca09808c43b1cf16aaf0ae5dba0b842ce49300ea9a3d600621e7f26d3deaeaa223b761
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -20,6 +20,11 @@ module ActiveSupport
|
|
20
20
|
raise UnsupportedOperation.new("decrement is not supported by: #{self.class.name}")
|
21
21
|
end
|
22
22
|
|
23
|
+
# IdentityCache has its own handling for read only.
|
24
|
+
def read_only
|
25
|
+
false
|
26
|
+
end
|
27
|
+
|
23
28
|
private
|
24
29
|
def serialize_entry(entry, options)
|
25
30
|
value = options[:raw] ? entry.value.to_s : Marshal.dump(entry)
|
@@ -30,6 +30,8 @@ module ActiveSupport
|
|
30
30
|
|
31
31
|
ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n
|
32
32
|
|
33
|
+
attr_accessor :read_only
|
34
|
+
|
33
35
|
def initialize(*addresses)
|
34
36
|
addresses = addresses.flatten
|
35
37
|
options = addresses.extract_options!
|
@@ -46,6 +48,21 @@ module ActiveSupport
|
|
46
48
|
extend Strategy::LocalCache
|
47
49
|
end
|
48
50
|
|
51
|
+
def logger
|
52
|
+
return @logger if defined?(@logger)
|
53
|
+
@logger = ::Rails.logger if defined?(::Rails)
|
54
|
+
end
|
55
|
+
|
56
|
+
def write(*args)
|
57
|
+
return true if read_only
|
58
|
+
super(*args)
|
59
|
+
end
|
60
|
+
|
61
|
+
def delete(*args)
|
62
|
+
return true if read_only
|
63
|
+
super(*args)
|
64
|
+
end
|
65
|
+
|
49
66
|
def read_multi(*names)
|
50
67
|
options = names.extract_options!
|
51
68
|
options = merged_options(options)
|
@@ -74,6 +91,7 @@ module ActiveSupport
|
|
74
91
|
@data.cas(key, expiration(options), cas_raw?(options)) do |raw_value|
|
75
92
|
entry = deserialize_entry(raw_value)
|
76
93
|
value = yield entry.value
|
94
|
+
break true if read_only
|
77
95
|
serialize_entry(Entry.new(value, options), options).first
|
78
96
|
end
|
79
97
|
end
|
@@ -83,6 +101,7 @@ module ActiveSupport
|
|
83
101
|
end
|
84
102
|
|
85
103
|
def cas_multi(*names)
|
104
|
+
|
86
105
|
options = names.extract_options!
|
87
106
|
options = merged_options(options)
|
88
107
|
keys_to_names = Hash[names.map{|name| [escape_key(namespaced_key(name, options)), name]}]
|
@@ -95,6 +114,7 @@ module ActiveSupport
|
|
95
114
|
values[keys_to_names[key]] = entry.value unless entry.expired?
|
96
115
|
end
|
97
116
|
values = yield values
|
117
|
+
break true if read_only
|
98
118
|
Hash[values.map{|name, value| [escape_key(namespaced_key(name, options)), serialize_entry(Entry.new(value, options), options).first]}]
|
99
119
|
end
|
100
120
|
end
|
@@ -151,6 +171,7 @@ module ActiveSupport
|
|
151
171
|
end
|
152
172
|
|
153
173
|
def write_entry(key, entry, options) # :nodoc:
|
174
|
+
return true if read_only
|
154
175
|
method = options && options[:unless_exist] ? :add : :set
|
155
176
|
expires_in = expiration(options)
|
156
177
|
value, raw = serialize_entry(entry, options)
|
@@ -161,6 +182,7 @@ module ActiveSupport
|
|
161
182
|
end
|
162
183
|
|
163
184
|
def delete_entry(key, options) # :nodoc:
|
185
|
+
return true if read_only
|
164
186
|
@data.delete(escape_key(key))
|
165
187
|
true
|
166
188
|
rescue *NONFATAL_EXCEPTIONS => e
|
@@ -23,6 +23,7 @@ module MemcachedStore
|
|
23
23
|
def exist_with_rescue?(*args)
|
24
24
|
exist_without_rescue?(*args)
|
25
25
|
rescue *NONFATAL_EXCEPTIONS
|
26
|
+
report_exception($!)
|
26
27
|
end
|
27
28
|
alias_method :exist_without_rescue?, :exist?
|
28
29
|
alias_method :exist?, :exist_with_rescue?
|
@@ -30,6 +31,7 @@ module MemcachedStore
|
|
30
31
|
def cas_with_rescue(*args)
|
31
32
|
cas_without_rescue(*args)
|
32
33
|
rescue *NONFATAL_EXCEPTIONS
|
34
|
+
report_exception($!)
|
33
35
|
false
|
34
36
|
end
|
35
37
|
alias_method_chain :cas, :rescue
|
@@ -37,6 +39,7 @@ module MemcachedStore
|
|
37
39
|
def get_multi_with_rescue(*args)
|
38
40
|
get_multi_without_rescue(*args)
|
39
41
|
rescue *NONFATAL_EXCEPTIONS
|
42
|
+
report_exception($!)
|
40
43
|
{}
|
41
44
|
end
|
42
45
|
alias_method_chain :get_multi, :rescue
|
@@ -44,6 +47,7 @@ module MemcachedStore
|
|
44
47
|
def set_with_rescue(*args)
|
45
48
|
set_without_rescue(*args)
|
46
49
|
rescue *NONFATAL_EXCEPTIONS
|
50
|
+
report_exception($!)
|
47
51
|
false
|
48
52
|
end
|
49
53
|
alias_method_chain :set, :rescue
|
@@ -51,6 +55,7 @@ module MemcachedStore
|
|
51
55
|
def add_with_rescue(*args)
|
52
56
|
add_without_rescue(*args)
|
53
57
|
rescue *NONFATAL_EXCEPTIONS
|
58
|
+
report_exception($!)
|
54
59
|
@string_return_types? "NOT STORED\r\n" : true
|
55
60
|
end
|
56
61
|
alias_method_chain :add, :rescue
|
@@ -60,9 +65,24 @@ module MemcachedStore
|
|
60
65
|
def #{meth}_with_rescue(*args)
|
61
66
|
#{meth}_without_rescue(*args)
|
62
67
|
rescue *NONFATAL_EXCEPTIONS
|
68
|
+
report_exception($!)
|
63
69
|
end
|
64
70
|
alias_method_chain :#{meth}, :rescue
|
65
71
|
ENV
|
66
72
|
end
|
73
|
+
|
74
|
+
def logger
|
75
|
+
return @logger if @logger
|
76
|
+
@logger = ::Rails.logger if defined?(::Rails)
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def report_exception(exception)
|
82
|
+
if defined?(::Rails)
|
83
|
+
logger.error "[#{self.class}] exception=#{exception}"
|
84
|
+
end
|
85
|
+
nil # make sure return value is nil
|
86
|
+
end
|
67
87
|
end
|
68
88
|
end
|
data/memcached_store.gemspec
CHANGED
@@ -19,8 +19,4 @@ Gem::Specification.new do |gem|
|
|
19
19
|
gem.add_runtime_dependency "memcached", "~> 1.8.0"
|
20
20
|
|
21
21
|
gem.add_development_dependency "rake"
|
22
|
-
gem.add_development_dependency "minitest"
|
23
|
-
gem.add_development_dependency "mocha"
|
24
|
-
gem.add_development_dependency "timecop"
|
25
|
-
gem.add_development_dependency "snappy"
|
26
22
|
end
|
data/shipit.rubygems.yml
CHANGED
data/test/test_helper.rb
CHANGED
@@ -5,3 +5,17 @@ require 'timecop'
|
|
5
5
|
require 'active_support/test_case'
|
6
6
|
|
7
7
|
require 'memcached_store'
|
8
|
+
|
9
|
+
class Rails
|
10
|
+
def self.logger
|
11
|
+
@logger ||= Logger.new("/dev/null")
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.env
|
15
|
+
Struct.new("Env") do
|
16
|
+
def self.test?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -125,6 +125,11 @@ class TestMemcachedSafety < ActiveSupport::TestCase
|
|
125
125
|
@cache.prepend("a-key", "other")
|
126
126
|
end
|
127
127
|
end
|
128
|
+
|
129
|
+
test "logger defaults to rails logger" do
|
130
|
+
assert_equal Rails.logger, @cache.logger
|
131
|
+
end
|
132
|
+
|
128
133
|
private
|
129
134
|
|
130
135
|
def expect_nonfatal(sym)
|
@@ -1,9 +1,13 @@
|
|
1
1
|
require 'test_helper'
|
2
|
+
require 'logger'
|
2
3
|
|
3
4
|
class TestMemcachedStore < ActiveSupport::TestCase
|
4
5
|
setup do
|
5
6
|
@cache = ActiveSupport::Cache.lookup_store(:memcached_store, expires_in: 60, support_cas: true)
|
6
7
|
@cache.clear
|
8
|
+
|
9
|
+
# Enable ActiveSupport notifications. Can be disabled in Rails 5.
|
10
|
+
Thread.current[:instrument_cache_store] = true
|
7
11
|
end
|
8
12
|
|
9
13
|
def test_write_not_found
|
@@ -153,26 +157,11 @@ class TestMemcachedStore < ActiveSupport::TestCase
|
|
153
157
|
assert_equal({"fu" => "baz"}, @cache.read_multi('foo', 'fu'))
|
154
158
|
end
|
155
159
|
|
156
|
-
def test_read_multi
|
157
|
-
@cache.write('foo', 'bar')
|
158
|
-
@cache.write('fu', 'baz')
|
159
|
-
@cache.write('fud', 'biz')
|
160
|
-
assert_equal({"foo" => "bar", "fu" => "baz"}, @cache.read_multi('foo', 'fu'))
|
161
|
-
end
|
162
|
-
|
163
160
|
def test_read_multi_not_found
|
164
161
|
expect_not_found
|
165
162
|
assert_equal({}, @cache.read_multi('foe', 'fue'))
|
166
163
|
end
|
167
164
|
|
168
|
-
def test_read_multi_with_expires
|
169
|
-
@cache.write('foo', 'bar', :expires_in => 0.001)
|
170
|
-
@cache.write('fu', 'baz')
|
171
|
-
@cache.write('fud', 'biz')
|
172
|
-
sleep(0.002)
|
173
|
-
assert_equal({"fu" => "baz"}, @cache.read_multi('foo', 'fu'))
|
174
|
-
end
|
175
|
-
|
176
165
|
def test_read_and_write_compressed_small_data
|
177
166
|
@cache.write('foo', 'bar', :compress => true)
|
178
167
|
assert_equal 'bar', @cache.read('foo')
|
@@ -388,15 +377,224 @@ class TestMemcachedStore < ActiveSupport::TestCase
|
|
388
377
|
assert_equal "", client.prefix_key, "should not send the namespace to the client"
|
389
378
|
assert_equal "foo::key", cache.send(:namespaced_key, "key", cache.options)
|
390
379
|
end
|
391
|
-
|
380
|
+
|
392
381
|
def test_reset
|
393
382
|
client = @cache.instance_variable_get(:@data)
|
394
383
|
client.expects(:reset).once
|
395
384
|
@cache.reset
|
396
385
|
end
|
397
386
|
|
387
|
+
def test_write_to_read_only_memcached_store_should_not_write
|
388
|
+
with_read_only(@cache) do
|
389
|
+
assert @cache.write("walrus", "awesome"), "Writing to a disabled memcached
|
390
|
+
store should return truthy to make clients not care"
|
391
|
+
|
392
|
+
assert_nil @cache.read("walrus"), "Key should have nil value in disabled cache"
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
def test_delete_with_read_only_memcached_store_should_not_delete
|
397
|
+
assert @cache.write("walrus", "big")
|
398
|
+
|
399
|
+
with_read_only(@cache) do
|
400
|
+
assert @cache.delete("walrus"), "Should return truthy when deleted to not raise in client"
|
401
|
+
end
|
402
|
+
|
403
|
+
assert_equal "big", @cache.read("walrus"), "Cache entry should not have been deleted from read only client"
|
404
|
+
end
|
405
|
+
|
406
|
+
def test_cas_with_read_only_memcached_store_should_not_s
|
407
|
+
called_block = false
|
408
|
+
@cache.write('walrus', 'slimy')
|
409
|
+
|
410
|
+
with_read_only(@cache) do
|
411
|
+
assert(@cache.cas('walrus') { |value|
|
412
|
+
assert_equal 'slimy', value
|
413
|
+
called_block = true
|
414
|
+
'full'
|
415
|
+
})
|
416
|
+
end
|
417
|
+
|
418
|
+
assert_equal 'slimy', @cache.read('walrus')
|
419
|
+
assert called_block, "CAS with read only should have called the inner block with an assertion"
|
420
|
+
end
|
421
|
+
|
422
|
+
def test_cas_multi_with_read_only_memcached_store_should_not_s
|
423
|
+
called_block = false
|
424
|
+
|
425
|
+
@cache.write('walrus', 'cool')
|
426
|
+
@cache.write('narwhal', 'horn')
|
427
|
+
|
428
|
+
with_read_only(@cache) do
|
429
|
+
assert(@cache.cas_multi('walrus', 'narwhal') {
|
430
|
+
called_block = true
|
431
|
+
{ "walrus" => "not cool", "narwhal" => "not with horns" }
|
432
|
+
})
|
433
|
+
end
|
434
|
+
|
435
|
+
assert_equal 'cool', @cache.read('walrus')
|
436
|
+
assert_equal 'horn', @cache.read('narwhal')
|
437
|
+
assert called_block, "CAS with read only should have called the inner block with an assertion"
|
438
|
+
end
|
439
|
+
|
440
|
+
def test_write_with_read_only_should_not_send_activesupport_notification
|
441
|
+
assert_notifications(/cache/, 0) do
|
442
|
+
with_read_only(@cache) do
|
443
|
+
assert @cache.write("walrus", "bestest")
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
def test_delete_with_read_only_should_not_send_activesupport_notification
|
449
|
+
assert_notifications(/cache/, 0) do
|
450
|
+
with_read_only(@cache) do
|
451
|
+
assert @cache.delete("walrus")
|
452
|
+
end
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
def test_fetch_with_expires_in_with_read_only_should_not_send_activesupport_notification
|
457
|
+
expires_in = 10
|
458
|
+
@cache.fetch("walrus", expires_in: expires_in) { "yo" }
|
459
|
+
|
460
|
+
Timecop.travel(Time.now + expires_in + 1) do
|
461
|
+
assert_notifications(/cache_write/, 0) do
|
462
|
+
with_read_only(@cache) do
|
463
|
+
@cache.fetch("walrus") { "no" }
|
464
|
+
end
|
465
|
+
end
|
466
|
+
end
|
467
|
+
end
|
468
|
+
|
469
|
+
def test_fetch_with_expired_entry_with_read_only_should_return_nil_and_not_delete_from_cache
|
470
|
+
expires_in = 10
|
471
|
+
@cache.fetch("walrus", expires_in: expires_in) { "yo" }
|
472
|
+
|
473
|
+
Timecop.travel(Time.now + expires_in + 1) do
|
474
|
+
with_read_only(@cache) do
|
475
|
+
value = @cache.fetch("walrus", expires_in: expires_in) { "no" }
|
476
|
+
|
477
|
+
assert_equal "no", value
|
478
|
+
refute @cache.fetch("walrus"), "Client should return nil for expired key"
|
479
|
+
assert_equal "yo", @cache.instance_variable_get(:@data).get("walrus").value
|
480
|
+
end
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
def test_fetch_with_expired_entry_and_race_condition_ttl_with_read_only_should_return_nil_and_not_delete_from_cache
|
485
|
+
expires_in = 10
|
486
|
+
race_condition_ttl = 10
|
487
|
+
@cache.fetch("walrus", expires_in: expires_in) { "yo" }
|
488
|
+
|
489
|
+
Timecop.travel(Time.now + expires_in + 1) do
|
490
|
+
with_read_only(@cache) do
|
491
|
+
value = @cache.fetch("walrus", expires_in: expires_in, race_condition_ttl: race_condition_ttl) { "no" }
|
492
|
+
|
493
|
+
assert_equal "no", value
|
494
|
+
assert_equal "no", @cache.fetch("walrus") { "no" }
|
495
|
+
refute @cache.fetch("walrus")
|
496
|
+
|
497
|
+
assert_equal "yo", @cache.instance_variable_get(:@data).get("walrus").value
|
498
|
+
end
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
502
|
+
def test_read_with_expired_with_read_only_entry_should_return_nil_and_not_delete_from_cache
|
503
|
+
expires_in = 10
|
504
|
+
@cache.fetch("walrus", expires_in: expires_in) { "yo" }
|
505
|
+
|
506
|
+
Timecop.travel(Time.now + expires_in + 1) do
|
507
|
+
with_read_only(@cache) do
|
508
|
+
refute @cache.read("walrus")
|
509
|
+
|
510
|
+
assert_equal "yo", @cache.instance_variable_get(:@data).get("walrus").value
|
511
|
+
end
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
def test_read_multi_with_expired_entry_should_return_nil_and_not_delete_from_cache
|
516
|
+
expires_in = 10
|
517
|
+
@cache.fetch("walrus", expires_in: expires_in) { "yo" }
|
518
|
+
@cache.fetch("narwhal", expires_in: expires_in) { "yiir" }
|
519
|
+
|
520
|
+
Timecop.travel(Time.now + expires_in + 1) do
|
521
|
+
with_read_only(@cache) do
|
522
|
+
assert_predicate @cache.read_multi("walrus", "narwhal"), :empty?
|
523
|
+
|
524
|
+
assert_equal "yo", @cache.instance_variable_get(:@data).get("walrus").value
|
525
|
+
assert_equal "yiir", @cache.instance_variable_get(:@data).get("narwhal").value
|
526
|
+
end
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
def test_fetch_with_race_condition_ttl_with_read_only_should_not_send_activesupport_notification
|
531
|
+
expires_in = 10
|
532
|
+
race_condition_ttl = 10
|
533
|
+
@cache.fetch("walrus", expires_in: expires_in) { "yo" }
|
534
|
+
|
535
|
+
Timecop.travel(Time.now + expires_in + 1) do
|
536
|
+
assert_notifications(/cache_write/, 0) do
|
537
|
+
with_read_only(@cache) do
|
538
|
+
@cache.fetch("walrus", expires_in: expires_in, race_condition_ttl: race_condition_ttl) { "no" }
|
539
|
+
end
|
540
|
+
end
|
541
|
+
end
|
542
|
+
end
|
543
|
+
|
544
|
+
def test_cas_with_read_only_should_send_activesupport_notification
|
545
|
+
@cache.write("walrus", "yes")
|
546
|
+
|
547
|
+
with_read_only(@cache) do
|
548
|
+
assert_notifications(/cache_cas/, 1) do
|
549
|
+
assert(@cache.cas("walrus") { |value| "no" })
|
550
|
+
end
|
551
|
+
end
|
552
|
+
|
553
|
+
assert_equal "yes", @cache.fetch("walrus")
|
554
|
+
end
|
555
|
+
|
556
|
+
def test_cas_multi_with_read_only_should_send_activesupport_notification
|
557
|
+
@cache.write("walrus", "yes")
|
558
|
+
@cache.write("narwhal", "yes")
|
559
|
+
|
560
|
+
with_read_only(@cache) do
|
561
|
+
assert_notifications(/cache_cas/, 1) do
|
562
|
+
assert(@cache.cas_multi("walrus", "narwhal") { |*values|
|
563
|
+
{ "walrus" => "no", "narwhal" => "no" }
|
564
|
+
})
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
assert_equal "yes", @cache.fetch("walrus")
|
569
|
+
assert_equal "yes", @cache.fetch("narwhal")
|
570
|
+
end
|
571
|
+
|
572
|
+
def test_logger_defaults_to_rails_logger
|
573
|
+
assert_equal Rails.logger, @cache.logger
|
574
|
+
end
|
575
|
+
|
398
576
|
private
|
399
577
|
|
578
|
+
def assert_notifications(pattern, num)
|
579
|
+
count = 0
|
580
|
+
subscriber = ActiveSupport::Notifications.subscribe(pattern) do |name, start, finish, id, payload|
|
581
|
+
count += 1
|
582
|
+
end
|
583
|
+
|
584
|
+
yield
|
585
|
+
|
586
|
+
assert_equal num, count, "Expected #{num} notifications for #{pattern}, but got #{count}"
|
587
|
+
ensure
|
588
|
+
ActiveSupport::Notifications.unsubscribe(subscriber)
|
589
|
+
end
|
590
|
+
|
591
|
+
def with_read_only(client)
|
592
|
+
previous, client.read_only = client.read_only, true
|
593
|
+
yield
|
594
|
+
ensure
|
595
|
+
client.read_only = previous
|
596
|
+
end
|
597
|
+
|
400
598
|
def expect_not_found
|
401
599
|
@cache.instance_variable_get(:@data).expects(:check_return_code).raises(Memcached::NotFound)
|
402
600
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memcached_store
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.12.
|
4
|
+
version: 0.12.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Camilo Lopez
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2016-11-30 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activesupport
|
@@ -55,62 +55,6 @@ dependencies:
|
|
55
55
|
- - ">="
|
56
56
|
- !ruby/object:Gem::Version
|
57
57
|
version: '0'
|
58
|
-
- !ruby/object:Gem::Dependency
|
59
|
-
name: minitest
|
60
|
-
requirement: !ruby/object:Gem::Requirement
|
61
|
-
requirements:
|
62
|
-
- - ">="
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: '0'
|
65
|
-
type: :development
|
66
|
-
prerelease: false
|
67
|
-
version_requirements: !ruby/object:Gem::Requirement
|
68
|
-
requirements:
|
69
|
-
- - ">="
|
70
|
-
- !ruby/object:Gem::Version
|
71
|
-
version: '0'
|
72
|
-
- !ruby/object:Gem::Dependency
|
73
|
-
name: mocha
|
74
|
-
requirement: !ruby/object:Gem::Requirement
|
75
|
-
requirements:
|
76
|
-
- - ">="
|
77
|
-
- !ruby/object:Gem::Version
|
78
|
-
version: '0'
|
79
|
-
type: :development
|
80
|
-
prerelease: false
|
81
|
-
version_requirements: !ruby/object:Gem::Requirement
|
82
|
-
requirements:
|
83
|
-
- - ">="
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
version: '0'
|
86
|
-
- !ruby/object:Gem::Dependency
|
87
|
-
name: timecop
|
88
|
-
requirement: !ruby/object:Gem::Requirement
|
89
|
-
requirements:
|
90
|
-
- - ">="
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
version: '0'
|
93
|
-
type: :development
|
94
|
-
prerelease: false
|
95
|
-
version_requirements: !ruby/object:Gem::Requirement
|
96
|
-
requirements:
|
97
|
-
- - ">="
|
98
|
-
- !ruby/object:Gem::Version
|
99
|
-
version: '0'
|
100
|
-
- !ruby/object:Gem::Dependency
|
101
|
-
name: snappy
|
102
|
-
requirement: !ruby/object:Gem::Requirement
|
103
|
-
requirements:
|
104
|
-
- - ">="
|
105
|
-
- !ruby/object:Gem::Version
|
106
|
-
version: '0'
|
107
|
-
type: :development
|
108
|
-
prerelease: false
|
109
|
-
version_requirements: !ruby/object:Gem::Requirement
|
110
|
-
requirements:
|
111
|
-
- - ">="
|
112
|
-
- !ruby/object:Gem::Version
|
113
|
-
version: '0'
|
114
58
|
description: Plugin-able Memcached adapters to add features (compression, safety)
|
115
59
|
email:
|
116
60
|
- camilo@camilolopez.com
|
@@ -157,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
101
|
version: '0'
|
158
102
|
requirements: []
|
159
103
|
rubyforge_project:
|
160
|
-
rubygems_version: 2.
|
104
|
+
rubygems_version: 2.5.1
|
161
105
|
signing_key:
|
162
106
|
specification_version: 4
|
163
107
|
summary: Plugin-able Memcached adapters to add features (compression, safety)
|