redis-objects 1.4.0 → 1.4.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 +5 -5
- data/.travis.yml +1 -3
- data/lib/redis/list.rb +4 -2
- data/lib/redis/lock.rb +20 -19
- data/lib/redis/objects.rb +5 -4
- data/lib/redis/objects/version.rb +1 -1
- data/spec/redis_objects_conn_spec.rb +15 -0
- data/spec/redis_objects_instance_spec.rb +28 -26
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7d42c057174f5a48560f104f08c5cf9bb25bd1772dd0684912a0094c4158840b
|
4
|
+
data.tar.gz: a0f945a9aede01c5623486576444c370cacd0e8a4fa2315511e7c1245339e489
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7dec3f8e9925f49601f629786a2e01ff4524483235831fc4afe02d7dd7491fb7723a8a3bf0b8034712c2bba6c9071ad00c03c214ffe5e7ddfed9e0749fb48ab4
|
7
|
+
data.tar.gz: 7055d7720a3512215a9e3f63426ffe4d81ff06ce4d118a2e6ce05193362cd50052e95269cd2aa56e8a97703ad1349181d5790e2e7aedbc13d04e68f84f2597b6
|
data/.travis.yml
CHANGED
data/lib/redis/list.rb
CHANGED
@@ -29,8 +29,9 @@ class Redis
|
|
29
29
|
# Add a member to the end of the list. Redis: RPUSH
|
30
30
|
def push(*values)
|
31
31
|
allow_expiration do
|
32
|
-
redis.rpush(key, values.map{|v| marshal(v) })
|
32
|
+
count = redis.rpush(key, values.map{|v| marshal(v) })
|
33
33
|
redis.ltrim(key, -options[:maxlength], -1) if options[:maxlength]
|
34
|
+
count
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
@@ -62,8 +63,9 @@ class Redis
|
|
62
63
|
# Add a member to the start of the list. Redis: LPUSH
|
63
64
|
def unshift(*values)
|
64
65
|
allow_expiration do
|
65
|
-
redis.lpush(key, values.map{|v| marshal(v) })
|
66
|
+
count = redis.lpush(key, values.map{|v| marshal(v) })
|
66
67
|
redis.ltrim(key, 0, options[:maxlength] - 1) if options[:maxlength]
|
68
|
+
count
|
67
69
|
end
|
68
70
|
end
|
69
71
|
|
data/lib/redis/lock.rb
CHANGED
@@ -33,28 +33,28 @@ class Redis
|
|
33
33
|
# Get the lock and execute the code block. Any other code that needs the lock
|
34
34
|
# (on any server) will spin waiting for the lock up to the :timeout
|
35
35
|
# that was specified when the lock was defined.
|
36
|
-
def lock
|
37
|
-
|
36
|
+
def lock
|
37
|
+
raise ArgumentError, 'Block not given' unless block_given?
|
38
|
+
expiration = generate_expiration
|
39
|
+
end_time = nil
|
38
40
|
try_until_timeout do
|
39
|
-
|
40
|
-
#
|
41
|
-
|
41
|
+
end_time = Time.now.to_i + expiration
|
42
|
+
# Set a NX record and use the Redis expiration mechanism.
|
43
|
+
# Empty value because the presence of it is enough to lock
|
44
|
+
# `px` only except an Integer in millisecond
|
45
|
+
break if redis.set(key, nil, px: expiration, nx: true)
|
42
46
|
|
43
|
-
#
|
44
|
-
#
|
45
|
-
|
46
|
-
if !@options[:expiration].nil?
|
47
|
+
# Backward compatibility code
|
48
|
+
# TODO: remove at the next major release for performance
|
49
|
+
unless @options[:expiration].nil?
|
47
50
|
old_expiration = redis.get(key).to_f
|
48
51
|
|
49
|
-
|
50
|
-
|
52
|
+
# Check it was not an empty string with `zero?` and
|
53
|
+
# the expiration time is passed.
|
54
|
+
if !old_expiration.zero? && old_expiration < Time.now.to_f
|
51
55
|
expiration = generate_expiration
|
52
|
-
|
53
|
-
|
54
|
-
# Since GETSET returns the old value of the lock, if the old expiration
|
55
|
-
# is still in the past, we know no one else has expired the locked
|
56
|
-
# and we now have it.
|
57
|
-
break if old_expiration < Time.now.to_f
|
56
|
+
end_time = Time.now.to_i + expiration
|
57
|
+
break if redis.set(key, nil, px: expiration)
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
@@ -66,14 +66,15 @@ class Redis
|
|
66
66
|
# it's not safe for us to remove it. Check how much time has passed since we
|
67
67
|
# wrote the lock key and only delete it if it hasn't expired (or we're not using
|
68
68
|
# lock expiration)
|
69
|
-
if @options[:expiration].nil? ||
|
69
|
+
if @options[:expiration].nil? || end_time > Time.now.to_f
|
70
70
|
redis.del(key)
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
+
# Return expiration in milliseconds
|
75
76
|
def generate_expiration
|
76
|
-
@options[:expiration].nil? ? 1 :
|
77
|
+
((@options[:expiration].nil? ? 1 : @options[:expiration].to_f) * 1000).to_i
|
77
78
|
end
|
78
79
|
|
79
80
|
private
|
data/lib/redis/objects.rb
CHANGED
@@ -61,10 +61,11 @@ class Redis
|
|
61
61
|
|
62
62
|
class << self
|
63
63
|
def redis=(conn)
|
64
|
-
|
64
|
+
Thread.current[:__redis_objects_redis] = Objects::ConnectionPoolProxy.proxy_if_needed(conn)
|
65
65
|
end
|
66
|
+
|
66
67
|
def redis
|
67
|
-
|
68
|
+
Thread.current[:__redis_objects_redis] || $redis || Redis.current ||
|
68
69
|
raise(NotConnected, "Redis::Objects.redis not set to a Redis.new connection")
|
69
70
|
end
|
70
71
|
|
@@ -90,11 +91,11 @@ class Redis
|
|
90
91
|
module ClassMethods
|
91
92
|
# Enable per-class connections (eg, User and Post can use diff redis-server)
|
92
93
|
def redis=(conn)
|
93
|
-
|
94
|
+
Thread.current[:__redis_objects_redis] = Objects::ConnectionPoolProxy.proxy_if_needed(conn)
|
94
95
|
end
|
95
96
|
|
96
97
|
def redis
|
97
|
-
|
98
|
+
Thread.current[:__redis_objects_redis] || Objects.redis
|
98
99
|
end
|
99
100
|
|
100
101
|
# Internal list of objects
|
@@ -41,6 +41,21 @@ describe 'Connection tests' do
|
|
41
41
|
obj.default_redis_value.clear
|
42
42
|
end
|
43
43
|
|
44
|
+
it "should be thread-safe when setting Redis::Objects.redis connection" do
|
45
|
+
Redis::Objects.redis = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT, :db => 23)
|
46
|
+
|
47
|
+
thr = Thread.new do
|
48
|
+
Redis::Objects.redis = Redis.new(:host => REDIS_HOST, :port => REDIS_PORT, :db => 24)
|
49
|
+
Redis::Objects.redis.connection[:id].ends_with?("/24").should == true
|
50
|
+
end
|
51
|
+
|
52
|
+
Redis::Objects.redis.connection[:id].ends_with?("/23").should == true
|
53
|
+
|
54
|
+
thr.join
|
55
|
+
|
56
|
+
Redis::Objects.redis.connection[:id].ends_with?("/23").should == true
|
57
|
+
end
|
58
|
+
|
44
59
|
it "should support mget" do
|
45
60
|
class CustomConnectionObject
|
46
61
|
include Redis::Objects
|
@@ -568,16 +568,15 @@ describe Redis::Lock do
|
|
568
568
|
REDIS_HANDLE.flushall
|
569
569
|
end
|
570
570
|
|
571
|
-
it "should
|
572
|
-
start = Time.now
|
571
|
+
it "should ttl to the expiration" do
|
573
572
|
expiry = 15
|
574
573
|
lock = Redis::Lock.new(:test_lock, :expiration => expiry)
|
575
574
|
lock.lock do
|
576
|
-
expiration = REDIS_HANDLE.
|
575
|
+
expiration = REDIS_HANDLE.ttl("test_lock")
|
577
576
|
|
578
577
|
# The expiration stored in redis should be 15 seconds from when we started
|
579
578
|
# or a little more
|
580
|
-
expiration.should.be.close(
|
579
|
+
expiration.should.be.close(expiration, 2.0)
|
581
580
|
end
|
582
581
|
|
583
582
|
# key should have been cleaned up
|
@@ -587,30 +586,13 @@ describe Redis::Lock do
|
|
587
586
|
it "should set value to 1 when no expiration is set" do
|
588
587
|
lock = Redis::Lock.new(:test_lock)
|
589
588
|
lock.lock do
|
590
|
-
REDIS_HANDLE.
|
589
|
+
REDIS_HANDLE.ttl('test_lock').should == 1
|
591
590
|
end
|
592
591
|
|
593
592
|
# key should have been cleaned up
|
594
593
|
REDIS_HANDLE.get("test_lock").should.be.nil
|
595
594
|
end
|
596
595
|
|
597
|
-
it "should let lock be gettable when lock is expired" do
|
598
|
-
expiry = 15
|
599
|
-
lock = Redis::Lock.new(:test_lock, :expiration => expiry, :timeout => 0.1)
|
600
|
-
|
601
|
-
# create a fake lock in the past
|
602
|
-
REDIS_HANDLE.set("test_lock", Time.now-(expiry + 60))
|
603
|
-
|
604
|
-
gotit = false
|
605
|
-
lock.lock do
|
606
|
-
gotit = true
|
607
|
-
end
|
608
|
-
|
609
|
-
# should get the lock because it has expired
|
610
|
-
gotit.should.be.true
|
611
|
-
REDIS_HANDLE.get("test_lock").should.be.nil
|
612
|
-
end
|
613
|
-
|
614
596
|
it "should not let non-expired locks be gettable" do
|
615
597
|
expiry = 15
|
616
598
|
lock = Redis::Lock.new(:test_lock, :expiration => expiry, :timeout => 0.1)
|
@@ -636,15 +618,15 @@ describe Redis::Lock do
|
|
636
618
|
REDIS_HANDLE.get("test_lock").should.not.be.nil
|
637
619
|
end
|
638
620
|
|
639
|
-
it "should
|
640
|
-
lock = Redis::Lock.new(:test_lock, :expiration => 0.
|
621
|
+
it "Redis should remove the key if lock is held past expiration" do
|
622
|
+
lock = Redis::Lock.new(:test_lock, :expiration => 0.1)
|
641
623
|
|
642
624
|
lock.lock do
|
643
|
-
sleep
|
625
|
+
sleep 0.2
|
644
626
|
end
|
645
627
|
|
646
628
|
# lock value should still be set since the lock was held for more than the expiry
|
647
|
-
REDIS_HANDLE.get("test_lock").should.
|
629
|
+
REDIS_HANDLE.get("test_lock").should.be.nil
|
648
630
|
end
|
649
631
|
|
650
632
|
it "should respond to #to_json" do
|
@@ -654,6 +636,26 @@ describe Redis::Lock do
|
|
654
636
|
it "should respond to #as_json" do
|
655
637
|
Redis::Lock.new(:test_lock).as_json.should.be.kind_of(Hash)
|
656
638
|
end
|
639
|
+
|
640
|
+
it "should deal with old lock format" do
|
641
|
+
expiry = 15
|
642
|
+
lock = Redis::Lock.new(:test_lock, expiration: expiry, timeout: 0.1)
|
643
|
+
|
644
|
+
# create a fake lock in the past
|
645
|
+
REDIS_HANDLE.set("test_lock", (Time.now - expiry).to_f)
|
646
|
+
|
647
|
+
gotit = false
|
648
|
+
lock.lock do
|
649
|
+
gotit = true
|
650
|
+
end
|
651
|
+
|
652
|
+
# should have the lock
|
653
|
+
gotit.should.be.true
|
654
|
+
|
655
|
+
# lock value should be unset
|
656
|
+
REDIS_HANDLE.get("test_lock").should.be.nil
|
657
|
+
end
|
658
|
+
|
657
659
|
end
|
658
660
|
|
659
661
|
describe Redis::HashKey do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-objects
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nate Wiger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -185,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
185
185
|
version: '0'
|
186
186
|
requirements: []
|
187
187
|
rubyforge_project:
|
188
|
-
rubygems_version: 2.
|
188
|
+
rubygems_version: 2.7.3
|
189
189
|
signing_key:
|
190
190
|
specification_version: 4
|
191
191
|
summary: Map Redis types directly to Ruby objects
|