asynchronic 3.0.3 → 4.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/README.md +1 -1
  4. data/lib/asynchronic/data_store/in_memory.rb +21 -16
  5. data/lib/asynchronic/data_store/key.rb +3 -3
  6. data/lib/asynchronic/data_store/lazy_value.rb +5 -3
  7. data/lib/asynchronic/data_store/redis.rb +22 -14
  8. data/lib/asynchronic/data_store/scoped_store.rb +18 -19
  9. data/lib/asynchronic/environment.rb +3 -3
  10. data/lib/asynchronic/error.rb +2 -3
  11. data/lib/asynchronic/garbage_collector.rb +2 -1
  12. data/lib/asynchronic/job.rb +12 -12
  13. data/lib/asynchronic/notifier/broadcaster.rb +8 -4
  14. data/lib/asynchronic/process.rb +36 -33
  15. data/lib/asynchronic/queue_engine/in_memory.rb +17 -11
  16. data/lib/asynchronic/queue_engine/ost.rb +7 -5
  17. data/lib/asynchronic/queue_engine/synchronic.rb +21 -9
  18. data/lib/asynchronic/version.rb +1 -1
  19. data/lib/asynchronic/worker.rb +7 -10
  20. data/lib/asynchronic.rb +8 -0
  21. data/spec/data_store/data_store_examples.rb +17 -9
  22. data/spec/data_store/in_memory_spec.rb +0 -2
  23. data/spec/data_store/key_spec.rb +1 -1
  24. data/spec/data_store/lazy_value_examples.rb +7 -5
  25. data/spec/data_store/redis_spec.rb +4 -10
  26. data/spec/expectations.rb +2 -2
  27. data/spec/facade_spec.rb +3 -3
  28. data/spec/jobs.rb +10 -10
  29. data/spec/minitest_helper.rb +5 -12
  30. data/spec/process/life_cycle_examples.rb +24 -22
  31. data/spec/process/life_cycle_in_memory_spec.rb +0 -1
  32. data/spec/process/life_cycle_redis_spec.rb +0 -1
  33. data/spec/queue_engine/in_memory_spec.rb +1 -3
  34. data/spec/queue_engine/ost_spec.rb +1 -7
  35. data/spec/queue_engine/queue_engine_examples.rb +17 -9
  36. data/spec/queue_engine/synchronic_spec.rb +1 -1
  37. data/spec/worker/in_memory_spec.rb +1 -2
  38. data/spec/worker/redis_spec.rb +0 -6
  39. data/spec/worker/worker_examples.rb +6 -4
  40. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7cc53216188aca01f66806e933e68d3edacda3dabca5e93b3da3eae1a41bbae5
4
- data.tar.gz: ad209146fc5b92f5d0d38c5d0ce27b72b6c6f7308831f9facb08a9bc7a538904
3
+ metadata.gz: b6b02a7e0922a83bdb5cc7602ab49fe6e89dac37d82f6666c97dc0014a94c1f6
4
+ data.tar.gz: c2c237b5ea9ca4b72335a0d02face23ac7ab49b1d42af69c816c31a2298ea890
5
5
  SHA512:
6
- metadata.gz: 3e826e042a938689168e9ca085d4fd5f28250ed350ebdb658c871415b36df88088e290712c72558256c1535b247ead901fbae3818e692895f6e4d8052ab5f560
7
- data.tar.gz: 2a1d517fb7cd29556d790e6680928e9294e79329b23a3e7ebab6e948ebc6a087d713cc2c3ca12908ca25f4798585198d35a88351c3f0723ad47d8e4b4416bb2d
6
+ metadata.gz: 56e6d3c61dd259657d8738160e4b82978b4e1898089a023b7b675fcb1680b4c01e67dae5bb1cc09e22da98b062c1f1c737263f37c209007dc796c65895613425
7
+ data.tar.gz: dc6a6cec5e3c628d2e15255aba71d078a0bbe1c11ad34d77023663c3de4d78089b1e41316dcfd95aab4ddad3e7547c2b400ddb3a70259a71b2be0c7771c6dfde
data/.travis.yml CHANGED
@@ -9,6 +9,7 @@ rvm:
9
9
  - 2.5
10
10
  - 2.6
11
11
  - 2.7
12
+ - 3.0
12
13
  - jruby-9.2.9.0
13
14
  - ruby-head
14
15
  - jruby-head
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Asynchronic
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/asynchronic.svg)](https://rubygems.org/gems/asynchronic)
4
- [![Build Status](https://travis-ci.org/gabynaiman/asynchronic.svg?branch=master)](https://travis-ci.org/gabynaiman/asynchronic)
4
+ [![Build Status](https://travis-ci.com/gabynaiman/asynchronic.svg?branch=master)](https://travis-ci.com/gabynaiman/asynchronic)
5
5
  [![Coverage Status](https://coveralls.io/repos/gabynaiman/asynchronic/badge.svg?branch=master)](https://coveralls.io/r/gabynaiman/asynchronic?branch=master)
6
6
  [![Code Climate](https://codeclimate.com/github/gabynaiman/asynchronic.svg)](https://codeclimate.com/github/gabynaiman/asynchronic)
7
7
 
@@ -4,51 +4,56 @@ module Asynchronic
4
4
 
5
5
  include Helper
6
6
 
7
- def initialize(hash={})
7
+ def self.connect(object_id)
8
+ connections[object_id]
9
+ end
10
+
11
+ def self.connections
12
+ @connections ||= {}
13
+ end
14
+
15
+ def initialize
8
16
  @hash = {}
9
17
  @mutex = Mutex.new
10
- @keys_mutex = Hash.new { |h,k| h[k] = Mutex.new }
18
+ @keys_mutex = {}
11
19
  self.class.connections[object_id] = self
12
20
  end
13
21
 
14
22
  def [](key)
15
- Marshal.load(@hash[key.to_s]) if @hash.key? key.to_s
23
+ Marshal.load(hash[key.to_s]) if hash.key? key.to_s
16
24
  end
17
25
 
18
26
  def []=(key, value)
19
- @mutex.synchronize { @hash[key.to_s] = Marshal.dump(value) }
27
+ mutex.synchronize { hash[key.to_s] = Marshal.dump(value) }
20
28
  end
21
29
 
22
30
  def delete(key)
23
- @hash.delete key.to_s
31
+ hash.delete key.to_s
24
32
  end
25
33
 
26
34
  def delete_cascade(key)
27
- keys = self.keys.select { |k| k.sections.first == key }
28
- keys.each { |k| delete k }
35
+ keys.select { |k| k.sections.first == key }
36
+ .each { |k| delete k }
29
37
  end
30
38
 
31
39
  def keys
32
- @hash.keys.map { |k| Key[k] }
40
+ hash.keys.map { |k| Key[k] }
33
41
  end
34
42
 
35
43
  def synchronize(key, &block)
36
- @keys_mutex[key].synchronize(&block)
44
+ mutex.synchronize do
45
+ keys_mutex[key] ||= Mutex.new
46
+ end
47
+ keys_mutex[key].synchronize(&block)
37
48
  end
38
49
 
39
50
  def connection_args
40
51
  [object_id]
41
52
  end
42
53
 
43
- def self.connect(object_id)
44
- connections[object_id]
45
- end
46
-
47
54
  private
48
55
 
49
- def self.connections
50
- @connections ||= {}
51
- end
56
+ attr_reader :hash, :mutex, :keys_mutex
52
57
 
53
58
  end
54
59
  end
@@ -1,19 +1,19 @@
1
1
  module Asynchronic
2
2
  module DataStore
3
3
  class Key < String
4
-
4
+
5
5
  SEPARATOR = '|'
6
6
 
7
7
  def self.[](key)
8
8
  new key
9
9
  end
10
-
10
+
11
11
  def initialize(key)
12
12
  super key.to_s
13
13
  end
14
14
 
15
15
  def [](key)
16
- self.class.new [self,key].join(SEPARATOR)
16
+ self.class.new [self, key].join(SEPARATOR)
17
17
  end
18
18
 
19
19
  def sections
@@ -14,11 +14,11 @@ module Asynchronic
14
14
  end
15
15
 
16
16
  def inspect
17
- "#<#{proxy_class} @data_store_class=#{@data_store_class} @data_store_connection_args=#{@data_store_connection_args} @key=#{@key}>"
17
+ "#<#{proxy_class} @data_store_class=#{data_store_class} @data_store_connection_args=#{data_store_connection_args} @key=#{key}>"
18
18
  end
19
19
 
20
20
  def data_store
21
- @data_store_class.connect(*@data_store_connection_args)
21
+ data_store_class.connect(*data_store_connection_args)
22
22
  end
23
23
 
24
24
  def to_value
@@ -27,8 +27,10 @@ module Asynchronic
27
27
 
28
28
  private
29
29
 
30
+ attr_reader :data_store_class, :data_store_connection_args, :key
31
+
30
32
  def __getobj__
31
- @value ||= data_store[@key]
33
+ @value ||= data_store[key]
32
34
  end
33
35
 
34
36
  end
@@ -6,13 +6,17 @@ module Asynchronic
6
6
 
7
7
  include Helper
8
8
 
9
- def initialize(scope, *args)
9
+ def self.connect(*args)
10
+ new(*args)
11
+ end
12
+
13
+ def initialize(scope, options={})
10
14
  @scope = Key[scope]
11
- @redis = Redic.new(*args)
15
+ @options = options
12
16
  end
13
17
 
14
18
  def [](key)
15
- value = @redis.call! 'GET', @scope[key]
19
+ value = redis.call! 'GET', scope[key]
16
20
  value ? Marshal.load(value) : nil
17
21
  rescue => ex
18
22
  Asynchronic.logger.warn('Asynchronic') { ex.message }
@@ -20,39 +24,43 @@ module Asynchronic
20
24
  end
21
25
 
22
26
  def []=(key, value)
23
- @redis.call! 'SET', @scope[key], Marshal.dump(value)
27
+ redis.call! 'SET', scope[key], Marshal.dump(value)
24
28
  end
25
29
 
26
30
  def delete(key)
27
- @redis.call! 'DEL', @scope[key]
31
+ redis.call! 'DEL', scope[key]
28
32
  end
29
33
 
30
34
  def delete_cascade(key)
31
- @redis.call! 'DEL', @scope[key]
32
- @redis.call!('KEYS', @scope[key]['*']).each { |k| @redis.call! 'DEL', k }
35
+ redis.call! 'DEL', scope[key]
36
+ redis.call!('KEYS', scope[key]['*']).each { |k| redis.call! 'DEL', k }
33
37
  end
34
38
 
35
39
  def keys
36
- @redis.call!('KEYS', @scope['*']).map { |k| Key[k].remove_first }
40
+ redis.call!('KEYS', scope['*']).map { |k| Key[k].remove_first }
37
41
  end
38
42
 
39
43
  def synchronize(key)
40
- while @redis.call!('GETSET', @scope[key][LOCKED], LOCKED) == LOCKED
44
+ while redis.call!('GETSET', scope[key][LOCKED], LOCKED) == LOCKED
41
45
  sleep Asynchronic.redis_data_store_sync_timeout
42
46
  end
43
47
  yield
44
48
  ensure
45
- @redis.call! 'DEL', @scope[key][LOCKED]
49
+ redis.call! 'DEL', scope[key][LOCKED]
46
50
  end
47
51
 
48
52
  def connection_args
49
- [@scope, @redis.url]
53
+ [scope, options]
50
54
  end
51
55
 
52
- def self.connect(*args)
53
- new(*args)
56
+ private
57
+
58
+ attr_reader :scope, :options
59
+
60
+ def redis
61
+ @redis ||= Asynchronic.establish_redis_connection options
54
62
  end
55
-
63
+
56
64
  end
57
65
  end
58
66
  end
@@ -4,34 +4,38 @@ module Asynchronic
4
4
 
5
5
  include Helper
6
6
 
7
- attr_reader :data_store
8
- attr_reader :scope
9
-
7
+ attr_reader :data_store, :scope
8
+
9
+ def self.connect(options)
10
+ data_store = options[:data_store_class].connect(*options[:data_store_connection_args])
11
+ new data_store, options[:scope]
12
+ end
13
+
10
14
  def initialize(data_store, scope)
11
15
  @data_store = data_store
12
16
  @scope = Key[scope]
13
17
  end
14
18
 
15
19
  def [](key)
16
- @data_store[@scope[key]]
20
+ data_store[scope[key]]
17
21
  end
18
22
 
19
23
  def []=(key, value)
20
- @data_store[@scope[key]] = value
24
+ data_store[scope[key]] = value
21
25
  end
22
26
 
23
27
  def delete(key)
24
- @data_store.delete @scope[key]
28
+ data_store.delete scope[key]
25
29
  end
26
30
 
27
31
  def delete_cascade
28
- @data_store.delete_cascade @scope
32
+ data_store.delete_cascade scope
29
33
  end
30
34
 
31
35
  def keys
32
- @data_store.keys.
33
- select { |k| k.start_with? @scope[''] }.
34
- map { |k| Key[k].remove_first @scope.sections.count }
36
+ data_store.keys
37
+ .select { |k| k.start_with? scope[''] }
38
+ .map { |k| Key[k].remove_first scope.sections.count }
35
39
  end
36
40
 
37
41
  def synchronize(key, &block)
@@ -41,20 +45,15 @@ module Asynchronic
41
45
  def connection_args
42
46
  [
43
47
  {
44
- data_store_class: @data_store.class,
45
- data_store_connection_args: @data_store.connection_args,
46
- scope: @scope
48
+ data_store_class: data_store.class,
49
+ data_store_connection_args: data_store.connection_args,
50
+ scope: scope
47
51
  }
48
52
  ]
49
53
  end
50
54
 
51
- def self.connect(*args)
52
- data_store = args[0][:data_store_class].connect *args[0][:data_store_connection_args]
53
- new data_store, args[0][:scope]
54
- end
55
-
56
55
  def to_s
57
- "#<#{self.class} @data_store=#{@data_store} @scope=#{@scope}>"
56
+ "#<#{self.class} @data_store=#{data_store} @scope=#{scope}>"
58
57
  end
59
58
 
60
59
  end
@@ -2,7 +2,7 @@ module Asynchronic
2
2
  class Environment
3
3
 
4
4
  attr_reader :queue_engine, :data_store, :notifier
5
-
5
+
6
6
  def initialize(queue_engine, data_store, notifier)
7
7
  @queue_engine = queue_engine
8
8
  @data_store = data_store
@@ -14,7 +14,7 @@ module Asynchronic
14
14
  end
15
15
 
16
16
  def default_queue
17
- queue(queue_engine.default_queue)
17
+ queue queue_engine.default_queue
18
18
  end
19
19
 
20
20
  def enqueue(msg, queue=nil)
@@ -28,7 +28,7 @@ module Asynchronic
28
28
  def load_process(id)
29
29
  Process.new self, id
30
30
  end
31
-
31
+
32
32
  def processes
33
33
  Process.all self
34
34
  end
@@ -1,9 +1,8 @@
1
1
  module Asynchronic
2
2
  class Error
3
3
 
4
- attr_reader :message
5
- attr_reader :backtrace
6
-
4
+ attr_reader :message, :backtrace
5
+
7
6
  def initialize(source)
8
7
  @message = source.respond_to?(:message) ? source.message : source.to_s
9
8
  @backtrace = source.respond_to?(:backtrace) ? source.backtrace : []
@@ -25,7 +25,8 @@ module Asynchronic
25
25
  begin
26
26
  processes.select(&condition).each(&:destroy)
27
27
  rescue => ex
28
- Asynchronic.logger.error('Asynchronic') { "#{ex.class}: #{ex.message}" }
28
+ error_message = "#{ex.class}: #{ex.message}\n#{ex.backtrace.join("\n")}"
29
+ Asynchronic.logger.error('Asynchronic') { error_message }
29
30
  end
30
31
  end
31
32
 
@@ -1,18 +1,6 @@
1
1
  module Asynchronic
2
2
  class Job
3
3
 
4
- def initialize(process)
5
- @process = process
6
- end
7
-
8
- def params
9
- @process.params
10
- end
11
-
12
- def result(reference)
13
- @process[reference].result
14
- end
15
-
16
4
  def self.queue(name=nil)
17
5
  name ? @queue = name : @queue
18
6
  end
@@ -23,6 +11,18 @@ module Asynchronic
23
11
  process.id
24
12
  end
25
13
 
14
+ def initialize(process)
15
+ @process = process
16
+ end
17
+
18
+ def params
19
+ process.params
20
+ end
21
+
22
+ def result(reference)
23
+ process[reference].result
24
+ end
25
+
26
26
  private
27
27
 
28
28
  attr_reader :process
@@ -8,23 +8,27 @@ module Asynchronic
8
8
  end
9
9
 
10
10
  def publish(pid, event, data=nil)
11
- @broadcaster.publish DataStore::Key[pid][event], data
11
+ broadcaster.publish DataStore::Key[pid][event], data
12
12
  end
13
13
 
14
14
  def subscribe(pid, event, &block)
15
- @broadcaster.subscribe DataStore::Key[pid][event] do |data|
15
+ broadcaster.subscribe DataStore::Key[pid][event] do |data|
16
16
  block.call data
17
17
  end
18
18
  end
19
19
 
20
20
  def unsubscribe(subscription_id)
21
- @broadcaster.unsubscribe subscription_id
21
+ broadcaster.unsubscribe subscription_id
22
22
  end
23
23
 
24
24
  def unsubscribe_all
25
- @broadcaster.unsubscribe_all
25
+ broadcaster.unsubscribe_all
26
26
  end
27
27
 
28
+ private
29
+
30
+ attr_reader :broadcaster
31
+
28
32
  end
29
33
  end
30
34
  end
@@ -19,6 +19,30 @@ module Asynchronic
19
19
 
20
20
  attr_reader :id
21
21
 
22
+ def self.create(environment, type, params={})
23
+ id = params.delete(:id) || SecureRandom.uuid
24
+
25
+ Asynchronic.logger.debug('Asynchronic') { "Created process #{type} - #{id} - #{params}" }
26
+
27
+ new(environment, id) do
28
+ self.type = type
29
+ self.name = (params.delete(:alias) || type).to_s
30
+ self.queue = params.delete(:queue) || type.queue || parent_queue
31
+ self.dependencies = Array(params.delete(:dependencies)) | Array(params.delete(:dependency)) | infer_dependencies(params)
32
+ self.params = params
33
+ self.data = {}
34
+ pending!
35
+ end
36
+ end
37
+
38
+ def self.all(environment)
39
+ environment.data_store.keys
40
+ .select { |k| k.sections.count == 2 && k.match(/created_at$/) }
41
+ .sort_by { |k| environment.data_store[k] }
42
+ .reverse
43
+ .map { |k| Process.new environment, k.remove_last }
44
+ end
45
+
22
46
  def initialize(environment, id, &block)
23
47
  @environment = environment
24
48
  @id = DataStore::Key[id]
@@ -50,7 +74,7 @@ module Asynchronic
50
74
  end
51
75
 
52
76
  def dead?
53
- (running? && !connected?) || processes.any?(&:dead?)
77
+ (running? && !connected?) || (!finalized? && processes.any?(&:dead?))
54
78
  end
55
79
 
56
80
  def abort_if_dead
@@ -84,9 +108,11 @@ module Asynchronic
84
108
  end
85
109
 
86
110
  def processes
87
- data_store.scoped(:processes).keys.
88
- select { |k| k.sections.count == 2 && k.match(/\|name$/) }.
89
- sort.map { |k| Process.new environment, id[:processes][k.remove_last] }
111
+ data_store.scoped(:processes)
112
+ .keys
113
+ .select { |k| k.sections.count == 2 && k.match(/\|name$/) }
114
+ .sort
115
+ .map { |k| Process.new environment, id[:processes][k.remove_last] }
90
116
  end
91
117
 
92
118
  def parent
@@ -107,11 +133,11 @@ module Asynchronic
107
133
 
108
134
  def dependencies
109
135
  return [] if parent.nil? || data_store[:dependencies].empty?
110
-
136
+
111
137
  parent_processes = parent.processes.each_with_object({}) do |process, hash|
112
138
  hash[process.name] = process
113
139
  end
114
-
140
+
115
141
  data_store[:dependencies].map { |d| parent_processes[d.to_s] }
116
142
  end
117
143
 
@@ -135,7 +161,7 @@ module Asynchronic
135
161
  wakeup_children
136
162
  end
137
163
  Asynchronic.logger.info('Asynchronic') { "Wakeup finalized #{type} (#{id})" }
138
-
164
+
139
165
  parent.wakeup if parent && finalized?
140
166
  end
141
167
 
@@ -151,29 +177,6 @@ module Asynchronic
151
177
  self.data = self.data.merge key => value
152
178
  end
153
179
 
154
- def self.create(environment, type, params={})
155
- id = params.delete(:id) || SecureRandom.uuid
156
-
157
- Asynchronic.logger.debug('Asynchronic') { "Created process #{type} - #{id} - #{params}" }
158
-
159
- new(environment, id) do
160
- self.type = type
161
- self.name = (params.delete(:alias) || type).to_s
162
- self.queue = params.delete(:queue) || type.queue || parent_queue
163
- self.dependencies = Array(params.delete(:dependencies)) | Array(params.delete(:dependency)) | infer_dependencies(params)
164
- self.params = params
165
- self.data = {}
166
- pending!
167
- end
168
- end
169
-
170
- def self.all(environment)
171
- environment.data_store.keys.
172
- select { |k| k.sections.count == 2 && k.match(/created_at$/) }.
173
- sort_by { |k| environment.data_store[k] }.reverse.
174
- map { |k| Process.new environment, k.remove_last }
175
- end
176
-
177
180
  private
178
181
 
179
182
  attr_reader :environment
@@ -194,10 +197,10 @@ module Asynchronic
194
197
 
195
198
  def status=(status)
196
199
  Asynchronic.logger.info('Asynchronic') { "#{status.to_s.capitalize} #{type} (#{id})" }
197
-
200
+
198
201
  data_store[:status] = status
199
202
  data_store[TIME_TRACKING_MAP[status]] = Time.now if TIME_TRACKING_MAP.key? status
200
-
203
+
201
204
  environment.notifier.publish id, :status_changed, status
202
205
  environment.notifier.publish id, :finalized if finalized?
203
206
  end
@@ -229,7 +232,7 @@ module Asynchronic
229
232
  self.result = job.call
230
233
  waiting!
231
234
  end
232
-
235
+
233
236
  rescue Exception => ex
234
237
  message = "Failed process #{type} (#{id})\n#{ex.class} #{ex.message}\n#{ex.backtrace.join("\n")}"
235
238
  Asynchronic.logger.error('Asynchronic') { message }
@@ -2,27 +2,25 @@ module Asynchronic
2
2
  module QueueEngine
3
3
  class InMemory
4
4
 
5
- attr_reader :default_queue
6
-
7
5
  def initialize(options={})
8
- @default_queue = options[:default_queue]
6
+ @options = options
9
7
  @queues ||= Hash.new { |h,k| h[k] = Queue.new }
10
8
  end
11
9
 
12
10
  def default_queue
13
- @default_queue ||= Asynchronic.default_queue
11
+ @default_queue ||= options.fetch(:default_queue, Asynchronic.default_queue)
14
12
  end
15
13
 
16
14
  def [](name)
17
- @queues[name]
15
+ queues[name]
18
16
  end
19
17
 
20
- def queues
21
- @queues.keys.map(&:to_sym)
18
+ def queue_names
19
+ queues.keys.map(&:to_sym)
22
20
  end
23
21
 
24
22
  def clear
25
- @queues.clear
23
+ queues.clear
26
24
  end
27
25
 
28
26
  def listener
@@ -37,12 +35,16 @@ module Asynchronic
37
35
  [Asynchronic.connection_name]
38
36
  end
39
37
 
38
+ private
39
+
40
+ attr_reader :queues, :options
41
+
40
42
 
41
43
  class Queue
42
44
 
43
45
  extend Forwardable
44
46
 
45
- def_delegators :@queue, :size, :empty?, :to_a
47
+ def_delegators :queue, :size, :empty?, :to_a
46
48
 
47
49
  def initialize
48
50
  @queue = []
@@ -50,13 +52,17 @@ module Asynchronic
50
52
  end
51
53
 
52
54
  def pop
53
- @mutex.synchronize { @queue.shift }
55
+ mutex.synchronize { queue.shift }
54
56
  end
55
57
 
56
58
  def push(message)
57
- @mutex.synchronize { @queue.push message }
59
+ mutex.synchronize { queue.push message }
58
60
  end
59
61
 
62
+ private
63
+
64
+ attr_reader :queue, :mutex
65
+
60
66
  end
61
67
 
62
68
 
@@ -5,22 +5,22 @@ module Asynchronic
5
5
  attr_reader :redis, :default_queue
6
6
 
7
7
  def initialize(options={})
8
- @redis = Redic.new(*Array(options[:redis]))
8
+ @redis = Asynchronic.establish_redis_connection options
9
9
  @default_queue = options.fetch(:default_queue, Asynchronic.default_queue)
10
10
  @queues ||= Hash.new { |h,k| h[k] = Queue.new k, redis }
11
11
  @keep_alive_thread = notify_keep_alive
12
12
  end
13
13
 
14
14
  def [](name)
15
- @queues[name]
15
+ queues[name]
16
16
  end
17
17
 
18
- def queues
19
- (@queues.values.map(&:key) | redis.call!('KEYS', 'ost:*')).map { |q| q.to_s[4..-1].to_sym }
18
+ def queue_names
19
+ (queues.values.map(&:key) | redis.call!('KEYS', 'ost:*')).map { |q| q.to_s[4..-1].to_sym }
20
20
  end
21
21
 
22
22
  def clear
23
- @queues.clear
23
+ queues.clear
24
24
  redis.call!('KEYS', 'ost:*').each { |k| redis.call!('DEL', k) }
25
25
  end
26
26
 
@@ -41,6 +41,8 @@ module Asynchronic
41
41
 
42
42
  private
43
43
 
44
+ attr_reader :queues
45
+
44
46
  def notify_keep_alive
45
47
  Thread.new do
46
48
  loop do