asynchronic 1.2.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/asynchronic/data_store/in_memory.rb +5 -0
- data/lib/asynchronic/data_store/redis.rb +12 -0
- data/lib/asynchronic/data_store/scoped_store.rb +4 -0
- data/lib/asynchronic/process.rb +12 -10
- data/lib/asynchronic/version.rb +1 -1
- data/spec/data_store/data_store_examples.rb +16 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5e63019f4cecfab21e005adaf3f0ca4cb18fac6
|
4
|
+
data.tar.gz: 208ef42aa7f3b6ed1a395650d09944b53e8d425d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff558de68371b4af458784cb02fdf2ca97e712f3525670608f5c1008a66bcf4d32072f73b6c7e3efa824d8a03c1ed13acb97976c474290316d30847df0a7c198
|
7
|
+
data.tar.gz: 86fcec1a2c20383b4dcc29dea9b1926f1b3ea52d61dabffe62482e7c3d1faefc872b48a9832c75afb3156af1cb335dd67709070726d2802e308d2f1323c0fe3c
|
@@ -7,6 +7,7 @@ module Asynchronic
|
|
7
7
|
def initialize(hash={})
|
8
8
|
@hash = {}
|
9
9
|
@mutex = Mutex.new
|
10
|
+
@keys_mutex = Hash.new { |h,k| h[k] = Mutex.new }
|
10
11
|
self.class.connections[object_id] = self
|
11
12
|
end
|
12
13
|
|
@@ -26,6 +27,10 @@ module Asynchronic
|
|
26
27
|
@hash.keys.map { |k| Key.new k }
|
27
28
|
end
|
28
29
|
|
30
|
+
def synchronize(key, &block)
|
31
|
+
@keys_mutex[key].synchronize &block
|
32
|
+
end
|
33
|
+
|
29
34
|
def connection_args
|
30
35
|
[object_id]
|
31
36
|
end
|
@@ -2,6 +2,9 @@ module Asynchronic
|
|
2
2
|
module DataStore
|
3
3
|
class Redis
|
4
4
|
|
5
|
+
TIMEOUT = 0.001
|
6
|
+
LOCKED = 'locked'
|
7
|
+
|
5
8
|
include Helper
|
6
9
|
|
7
10
|
def initialize(scope, *args)
|
@@ -29,6 +32,15 @@ module Asynchronic
|
|
29
32
|
@connection.keys(@scope['*']).map { |k| Key.new(k).remove_first }
|
30
33
|
end
|
31
34
|
|
35
|
+
def synchronize(key)
|
36
|
+
while @connection.getset(@scope[key][LOCKED], LOCKED) == LOCKED
|
37
|
+
sleep TIMEOUT
|
38
|
+
end
|
39
|
+
yield
|
40
|
+
ensure
|
41
|
+
@connection.del @scope[key][LOCKED]
|
42
|
+
end
|
43
|
+
|
32
44
|
def connection_args
|
33
45
|
[@scope, @connection.client.options]
|
34
46
|
end
|
data/lib/asynchronic/process.rb
CHANGED
@@ -85,19 +85,21 @@ module Asynchronic
|
|
85
85
|
end
|
86
86
|
|
87
87
|
def wakeup
|
88
|
-
|
89
|
-
if
|
90
|
-
|
91
|
-
|
92
|
-
completed
|
93
|
-
|
94
|
-
|
95
|
-
|
88
|
+
data_store.synchronize(id) do
|
89
|
+
if waiting?
|
90
|
+
if processes.any?(&:aborted?)
|
91
|
+
abort! Error.new "Error caused by #{processes.select(&:aborted?).map{|p| p.name}.join(', ')}"
|
92
|
+
elsif processes.all?(&:completed?)
|
93
|
+
completed!
|
94
|
+
else
|
95
|
+
processes.each do |p|
|
96
|
+
p.enqueue if p.ready?
|
97
|
+
end
|
96
98
|
end
|
97
99
|
end
|
98
|
-
end
|
99
100
|
|
100
|
-
|
101
|
+
parent.wakeup if parent && finalized?
|
102
|
+
end
|
101
103
|
end
|
102
104
|
|
103
105
|
def nest(type, params={})
|
data/lib/asynchronic/version.rb
CHANGED
@@ -90,5 +90,21 @@ module DataStoreExamples
|
|
90
90
|
|
91
91
|
no_lazy_store[:key].must_equal 2
|
92
92
|
end
|
93
|
+
|
94
|
+
it 'Synchronization' do
|
95
|
+
sum = 0
|
96
|
+
threads = 1.upto(100).map do |i|
|
97
|
+
Thread.new do
|
98
|
+
data_store.synchronize('xxx') do
|
99
|
+
temp = sum
|
100
|
+
sleep 0
|
101
|
+
sum = temp + 1
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
threads.each(&:join)
|
106
|
+
|
107
|
+
sum.must_equal 100
|
108
|
+
end
|
93
109
|
|
94
110
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asynchronic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gabriel Naiman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|