redstruct 0.2.1 → 0.2.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 +4 -4
- data/lib/redstruct/lock.rb +15 -6
- data/lib/redstruct/utils/atomic_counter.rb +30 -0
- data/lib/redstruct/version.rb +1 -1
- data/test/redstruct/lock_test.rb +16 -0
- data/test/redstruct/script_test.rb +1 -1
- data/test/test_helper.rb +3 -21
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2af38a102227eedaa6ed3d2f8efd91b02dcae8a0
|
4
|
+
data.tar.gz: 49041b97b9b1074aaac1986b792ea2ba72b7e3cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f1b9391762f28ec0686ce2f5b54b756b31e6640d63c51448b26d6d8948564a55916ff78f419edcba8310bdb3b79f91ad680fe5d17ad842e14fdda2528139823
|
7
|
+
data.tar.gz: 0abdd88f1387ea57ef1546ef35bae91fc783c631287c412705867ebbc148c093f9d5293aa208aec6b5f1fb964f8b0feedb2f3364c9f7338a6fef3f6f26d29fa0
|
data/lib/redstruct/lock.rb
CHANGED
@@ -4,6 +4,7 @@ require 'securerandom'
|
|
4
4
|
require 'redstruct/factory/object'
|
5
5
|
require 'redstruct/utils/scriptable'
|
6
6
|
require 'redstruct/utils/coercion'
|
7
|
+
require 'redstruct/utils/atomic_counter'
|
7
8
|
|
8
9
|
module Redstruct
|
9
10
|
# Implementation of a simple binary lock (locked/not locked), with option to block and wait for the lock.
|
@@ -39,6 +40,8 @@ module Redstruct
|
|
39
40
|
@resource = resource
|
40
41
|
@token = nil
|
41
42
|
@expiry = expiry
|
43
|
+
@acquired = Redstruct::Utils::AtomicCounter.new
|
44
|
+
|
42
45
|
@timeout = case timeout
|
43
46
|
when nil then nil
|
44
47
|
when Float::INFINITY then 0
|
@@ -96,6 +99,8 @@ module Redstruct
|
|
96
99
|
unless token.nil?
|
97
100
|
@lease.expire(@expiry)
|
98
101
|
@token = token
|
102
|
+
@acquired.increment
|
103
|
+
|
99
104
|
acquired = true
|
100
105
|
end
|
101
106
|
|
@@ -108,20 +113,24 @@ module Redstruct
|
|
108
113
|
def release
|
109
114
|
return false if @token.nil?
|
110
115
|
|
111
|
-
|
112
|
-
argv = [@token, generate_token, (@expiry.to_f * 1000).floor]
|
116
|
+
released = true
|
113
117
|
|
114
|
-
|
115
|
-
|
118
|
+
if @acquired.decrement.zero?
|
119
|
+
keys = [@lease.key, @tokens.key]
|
120
|
+
argv = [@token, generate_token, (@expiry.to_f * 1000).floor]
|
121
|
+
|
122
|
+
released = coerce_bool(release_script(keys: keys, argv: argv))
|
123
|
+
@token = nil
|
124
|
+
end
|
116
125
|
|
117
|
-
return
|
126
|
+
return released
|
118
127
|
end
|
119
128
|
|
120
129
|
private
|
121
130
|
|
122
131
|
def non_blocking_acquire
|
123
132
|
keys = [@lease.key, @tokens.key]
|
124
|
-
argv = [generate_token]
|
133
|
+
argv = [@token || generate_token]
|
125
134
|
|
126
135
|
return acquire_script(keys: keys, argv: argv)
|
127
136
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Redstruct
|
4
|
+
module Utils
|
5
|
+
# Very basic utility class to have thread-safe counters
|
6
|
+
class AtomicCounter
|
7
|
+
# @param [Integer] initial the initial value of the counter
|
8
|
+
def initialize(initial = 0)
|
9
|
+
@lock = Mutex.new
|
10
|
+
@current = initial
|
11
|
+
end
|
12
|
+
|
13
|
+
# Increments the counter by the given delta
|
14
|
+
# @param [Integer] by the delta to increment by
|
15
|
+
# @return [Integer] the new, incremented value
|
16
|
+
def increment(by: 1)
|
17
|
+
return @lock.synchronize do
|
18
|
+
@current += by.to_i
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Decrements the counter by the given delta
|
23
|
+
# @param [Integer] by the delta to decrement by
|
24
|
+
# @return [Integer] the new, decremented value
|
25
|
+
def decrement(by: 1)
|
26
|
+
return increment(by: -by.to_i)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/redstruct/version.rb
CHANGED
data/test/redstruct/lock_test.rb
CHANGED
@@ -109,6 +109,22 @@ module Redstruct
|
|
109
109
|
assert lock.acquire, 'should be to acquire the lock again since it was deleted'
|
110
110
|
end
|
111
111
|
|
112
|
+
def test_nested
|
113
|
+
lock = create
|
114
|
+
nested = false
|
115
|
+
|
116
|
+
lock.locked do
|
117
|
+
lock.locked do
|
118
|
+
nested = true
|
119
|
+
end
|
120
|
+
|
121
|
+
refute_nil lock.token, 'should still own the lock'
|
122
|
+
assert lock.acquire, 'should still own the lock'
|
123
|
+
end
|
124
|
+
|
125
|
+
assert nested, 'should have turned on the nested flag'
|
126
|
+
end
|
127
|
+
|
112
128
|
private
|
113
129
|
|
114
130
|
def create(resource = nil, **options)
|
data/test/test_helper.rb
CHANGED
@@ -5,6 +5,7 @@ require 'securerandom'
|
|
5
5
|
require 'bundler/setup'
|
6
6
|
require 'minitest/autorun'
|
7
7
|
require 'flexmock/minitest'
|
8
|
+
require 'redstruct/utils/atomic_counter'
|
8
9
|
|
9
10
|
ci_build = ENV['CI_BUILD'].to_i.positive?
|
10
11
|
|
@@ -30,37 +31,18 @@ Minitest.after_run do
|
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
33
|
-
# Small class used to generate thread-safe sequence when creating per-test
|
34
|
-
# factories
|
35
|
-
class AtomicInteger
|
36
|
-
def initialize
|
37
|
-
@lock = Mutex.new
|
38
|
-
@current = 0
|
39
|
-
end
|
40
|
-
|
41
|
-
def incr
|
42
|
-
value = nil
|
43
|
-
@lock.synchronize do
|
44
|
-
value = @current
|
45
|
-
@current += 1
|
46
|
-
end
|
47
|
-
|
48
|
-
return value
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
34
|
module Redstruct
|
53
35
|
# Base class for all Redstruct tests. Configures the gem, provides a default factory, and makes sure to clean it up
|
54
36
|
# at the end
|
55
37
|
class Test < Minitest::Test
|
56
|
-
@@counter =
|
38
|
+
@@counter = Redstruct::Utils::AtomicCounter.new # rubocop: disable Style/ClassVars
|
57
39
|
|
58
40
|
parallelize_me!
|
59
41
|
make_my_diffs_pretty!
|
60
42
|
|
61
43
|
# Use this helper to create a factory that the test class will keep track of and remove at the end
|
62
44
|
def create_factory(namespace = nil)
|
63
|
-
namespace ||= "#{Redstruct.config.default_namespace}:#{@@counter.
|
45
|
+
namespace ||= "#{Redstruct.config.default_namespace}:#{@@counter.increment}"
|
64
46
|
return Redstruct::Factory.new(namespace: namespace)
|
65
47
|
end
|
66
48
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redstruct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicolas Pepin-Perreault
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -113,6 +113,7 @@ files:
|
|
113
113
|
- lib/redstruct/sorted_set/slice.rb
|
114
114
|
- lib/redstruct/string.rb
|
115
115
|
- lib/redstruct/struct.rb
|
116
|
+
- lib/redstruct/utils/atomic_counter.rb
|
116
117
|
- lib/redstruct/utils/coercion.rb
|
117
118
|
- lib/redstruct/utils/inspectable.rb
|
118
119
|
- lib/redstruct/utils/iterable.rb
|