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 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