asynchronic 1.2.0 → 1.2.1

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
2
  SHA1:
3
- metadata.gz: 823dcc2c35bf1f7df17c20f250353123fa85c205
4
- data.tar.gz: c6f9507f48e4cb8b4e17051dcf30333bb1747b0b
3
+ metadata.gz: f5e63019f4cecfab21e005adaf3f0ca4cb18fac6
4
+ data.tar.gz: 208ef42aa7f3b6ed1a395650d09944b53e8d425d
5
5
  SHA512:
6
- metadata.gz: 30d4424ab6e16190dbcd2404259bfa0720db02e092d6998f3fd8c1129e0e1d4b47064aed4a4a571dd85a5f3ab871a8a11091ca22c2a9d9d5d759e568c6efda8d
7
- data.tar.gz: deb0672e6e9d1e4bf01017a8db5775cf6c2b57dc5e65257c333f7e8dd1fbb60e0562ff9dbe9533ec57bb5f74adc891967d48a2d80bcefd658b163a1a95f49d3e
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
@@ -30,6 +30,10 @@ module Asynchronic
30
30
  map { |k| Key.new(k).remove_first @scope.sections.count }
31
31
  end
32
32
 
33
+ def synchronize(key, &block)
34
+ data_store.synchronize(key, &block)
35
+ end
36
+
33
37
  def connection_args
34
38
  [
35
39
  {
@@ -85,19 +85,21 @@ module Asynchronic
85
85
  end
86
86
 
87
87
  def wakeup
88
- if waiting?
89
- if processes.any?(&:aborted?)
90
- abort! Error.new "Error caused by #{processes.select(&:aborted?).map{|p| p.name}.join(', ')}"
91
- elsif processes.all?(&:completed?)
92
- completed!
93
- else
94
- processes.each do |p|
95
- p.enqueue if p.ready?
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
- parent.wakeup if parent && finalized?
101
+ parent.wakeup if parent && finalized?
102
+ end
101
103
  end
102
104
 
103
105
  def nest(type, params={})
@@ -1,3 +1,3 @@
1
1
  module Asynchronic
2
- VERSION = '1.2.0'
2
+ VERSION = '1.2.1'
3
3
  end
@@ -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.0
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-18 00:00:00.000000000 Z
11
+ date: 2017-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis