redis-objects 1.4.0 → 1.4.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b251574cff0d3540f3cf018eb1b8bc0a5fa84ff8
4
- data.tar.gz: 0415ef6e0c853df6a864dcf994b5b644cd2fb722
2
+ SHA256:
3
+ metadata.gz: 7d42c057174f5a48560f104f08c5cf9bb25bd1772dd0684912a0094c4158840b
4
+ data.tar.gz: a0f945a9aede01c5623486576444c370cacd0e8a4fa2315511e7c1245339e489
5
5
  SHA512:
6
- metadata.gz: 76da3c02a6cbd7b221bd2b53dad1fdf54d3ad8efebb26c7e6fc79be8f5775c37113c572facfb362820f255b2fad94cef7eeb8010a24ab0a7c54f2f94cd4c20c1
7
- data.tar.gz: 588c4caa7ff2518b190d6970d3725d48caac5d1f9ad8faef894c815d9cf97716cdacff58acefb545d47df37c8129cdcb1dd108d7f6ab5d328b9be7fb744e791f
6
+ metadata.gz: 7dec3f8e9925f49601f629786a2e01ff4524483235831fc4afe02d7dd7491fb7723a8a3bf0b8034712c2bba6c9071ad00c03c214ffe5e7ddfed9e0749fb48ab4
7
+ data.tar.gz: 7055d7720a3512215a9e3f63426ffe4d81ff06ce4d118a2e6ce05193362cd50052e95269cd2aa56e8a97703ad1349181d5790e2e7aedbc13d04e68f84f2597b6
@@ -5,9 +5,7 @@ before_install:
5
5
  - gem install bundler
6
6
 
7
7
  rvm:
8
- - 1.9.3
9
- - 2.0.0
10
- - 2.1
11
8
  - 2.2
12
9
  - 2.3.3
13
10
  - 2.4.0
11
+ - 2.5.1
@@ -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
 
@@ -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(&block)
37
- expiration = nil
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
- expiration = generate_expiration
40
- # Use the expiration as the value of the lock.
41
- break if redis.setnx(key, expiration)
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
- # Lock is being held. Now check to see if it's expired (if we're using
44
- # lock expiration).
45
- # See "Handling Deadlocks" section on http://redis.io/commands/setnx
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
- if old_expiration < Time.now.to_f
50
- # If it's expired, use GETSET to update it.
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
- old_expiration = redis.getset(key, expiration).to_f
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? || expiration > Time.now.to_f
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 : (Time.now + @options[:expiration].to_f + 1).to_f
77
+ ((@options[:expiration].nil? ? 1 : @options[:expiration].to_f) * 1000).to_i
77
78
  end
78
79
 
79
80
  private
@@ -61,10 +61,11 @@ class Redis
61
61
 
62
62
  class << self
63
63
  def redis=(conn)
64
- @redis = Objects::ConnectionPoolProxy.proxy_if_needed(conn)
64
+ Thread.current[:__redis_objects_redis] = Objects::ConnectionPoolProxy.proxy_if_needed(conn)
65
65
  end
66
+
66
67
  def redis
67
- @redis || $redis || Redis.current ||
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
- @redis = Objects::ConnectionPoolProxy.proxy_if_needed(conn)
94
+ Thread.current[:__redis_objects_redis] = Objects::ConnectionPoolProxy.proxy_if_needed(conn)
94
95
  end
95
96
 
96
97
  def redis
97
- @redis || Objects.redis
98
+ Thread.current[:__redis_objects_redis] || Objects.redis
98
99
  end
99
100
 
100
101
  # Internal list of objects
@@ -1,5 +1,5 @@
1
1
  class Redis
2
2
  module Objects
3
- VERSION = "1.4.0"
3
+ VERSION = "1.4.2"
4
4
  end
5
5
  end
@@ -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 set the value to the expiration" do
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.get("test_lock").to_f
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((start + expiry).to_f, 2.0)
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.get('test_lock').should == '1'
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 not remove the key if lock is held past expiration" do
640
- lock = Redis::Lock.new(:test_lock, :expiration => 0.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 1.1
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.not.be.nil
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.0
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: 2017-12-07 00:00:00.000000000 Z
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.4.5
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