derfred-workling 0.4.9.2 → 0.4.9.3

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.
Files changed (58) hide show
  1. data/bin/workling_client +9 -7
  2. data/{script → contrib}/bj_invoker.rb +0 -0
  3. data/{script → contrib}/starling_status.rb +0 -0
  4. data/lib/{cattr_accessor.rb → extensions/cattr_accessor.rb} +0 -0
  5. data/lib/{mattr_accessor.rb → extensions/mattr_accessor.rb} +0 -0
  6. data/lib/workling.rb +98 -94
  7. data/lib/workling/base.rb +6 -11
  8. data/lib/workling/clients/amqp_client.rb +13 -5
  9. data/lib/workling/clients/amqp_exchange_client.rb +19 -11
  10. data/lib/workling/clients/backgroundjob_client.rb +25 -0
  11. data/lib/workling/clients/base.rb +40 -8
  12. data/lib/workling/clients/broker_base.rb +63 -0
  13. data/lib/workling/clients/memcache_queue_client.rb +24 -12
  14. data/lib/workling/clients/memory_queue_client.rb +34 -0
  15. data/lib/workling/clients/not_client.rb +14 -0
  16. data/lib/workling/clients/not_remote_client.rb +17 -0
  17. data/lib/workling/clients/spawn_client.rb +47 -0
  18. data/lib/workling/clients/sqs_client.rb +9 -8
  19. data/lib/workling/clients/thread_client.rb +18 -0
  20. data/lib/workling/clients/xmpp_client.rb +14 -4
  21. data/lib/workling/discovery.rb +1 -1
  22. data/lib/workling/invokers/amqp_single_subscriber.rb +42 -0
  23. data/lib/workling/invokers/base.rb +124 -0
  24. data/lib/workling/invokers/basic_poller.rb +38 -0
  25. data/lib/workling/invokers/eventmachine_subscriber.rb +38 -0
  26. data/lib/workling/invokers/looped_subscriber.rb +34 -0
  27. data/lib/workling/invokers/thread_pool_poller.rb +165 -0
  28. data/lib/workling/invokers/threaded_poller.rb +149 -0
  29. data/lib/workling/remote.rb +10 -41
  30. data/lib/workling/return/store/base.rb +7 -7
  31. data/lib/workling/return/store/memory_return_store.rb +0 -2
  32. data/lib/workling/return/store/starling_return_store.rb +7 -8
  33. data/lib/workling/routing/base.rb +1 -4
  34. data/lib/workling/routing/class_and_method_routing.rb +0 -2
  35. data/lib/workling/routing/static_routing.rb +0 -4
  36. data/lib/{workling_server.rb → workling_daemon.rb} +27 -25
  37. metadata +21 -28
  38. data/lib/rude_q/client.rb +0 -11
  39. data/lib/workling/remote/invokers/amqp_single_subscriber.rb +0 -45
  40. data/lib/workling/remote/invokers/base.rb +0 -124
  41. data/lib/workling/remote/invokers/basic_poller.rb +0 -41
  42. data/lib/workling/remote/invokers/eventmachine_subscriber.rb +0 -41
  43. data/lib/workling/remote/invokers/looped_subscriber.rb +0 -38
  44. data/lib/workling/remote/invokers/thread_pool_poller.rb +0 -169
  45. data/lib/workling/remote/invokers/threaded_poller.rb +0 -153
  46. data/lib/workling/remote/runners/amqp_exchange_runner.rb +0 -45
  47. data/lib/workling/remote/runners/backgroundjob_runner.rb +0 -35
  48. data/lib/workling/remote/runners/base.rb +0 -42
  49. data/lib/workling/remote/runners/client_runner.rb +0 -46
  50. data/lib/workling/remote/runners/not_remote_runner.rb +0 -23
  51. data/lib/workling/remote/runners/not_runner.rb +0 -17
  52. data/lib/workling/remote/runners/rudeq_runner.rb +0 -23
  53. data/lib/workling/remote/runners/spawn_runner.rb +0 -38
  54. data/lib/workling/remote/runners/starling_runner.rb +0 -13
  55. data/lib/workling/return/store/rudeq_return_store.rb +0 -24
  56. data/lib/workling/rudeq.rb +0 -7
  57. data/lib/workling/rudeq/client.rb +0 -17
  58. data/lib/workling/rudeq/poller.rb +0 -116
@@ -1,9 +1,3 @@
1
- require "workling/remote/runners/not_remote_runner"
2
- require "workling/remote/runners/spawn_runner"
3
- require "workling/remote/runners/starling_runner"
4
- require "workling/remote/runners/backgroundjob_runner"
5
- require "workling/remote/invokers/threaded_poller"
6
-
7
1
  require 'digest/md5'
8
2
 
9
3
  #
@@ -12,43 +6,18 @@ require 'digest/md5'
12
6
  module Workling
13
7
  module Remote
14
8
 
15
- # Select which invoke to load based on what is defined in workling.yml. Defaults to thread_poller
16
- # if none are specified.
17
- def self.select_invoker
18
- case(Workling.config[:invoker])
19
- when 'basic_poller'
20
- Workling::Remote::Invokers::BasicPoller
21
-
22
- when 'thread_pool_poller'
23
- Workling::Remote::Invokers::ThreadPoolPoller
24
-
25
- when 'eventmachine_subscriber'
26
- Workling::Remote::Invokers::EventmachineSubscriber
27
-
28
- when 'threaded_poller', nil
29
- Workling::Remote::Invokers::ThreadedPoller
30
-
31
- else
32
- Workling.logger.error("Nothing is known about #{Workling.config[:invoker]} defaulting to thread_poller")
33
- Workling::Remote::Invokers::ThreadedPoller
34
- end
9
+ # which object to use for routing
10
+ mattr_writer :routing
11
+ def self.routing
12
+ @@routing ||= Workling::Routing::ClassAndMethodRouting.new
35
13
  end
36
14
 
37
- # set the desired runner here. this is initialized with Workling.default_runner.
38
- mattr_accessor :dispatcher
39
-
40
- # set the desired invoker. this class grabs work from the job broker and executes it.
41
- mattr_accessor :invoker
42
- @@invoker ||= self.select_invoker
43
-
44
- mattr_accessor :routing
45
- @@routing ||= Workling::Routing::ClassAndMethodRouting
46
-
47
- # retrieve the dispatcher or instantiate it using the defaults
48
- def self.dispatcher
49
- @@dispatcher ||= Workling.default_runner
15
+ # which client to use for dispatching
16
+ mattr_accessor :client
17
+ def self.client
18
+ @@client ||= Workling.select_and_build_client
50
19
  end
51
-
20
+
52
21
  # generates a unique identifier for this particular job.
53
22
  def self.generate_uid(clazz, method)
54
23
  uid = ::Digest::MD5.hexdigest("#{ clazz }:#{ method }:#{ rand(1 << 64) }:#{ Time.now }")
@@ -61,7 +30,7 @@ module Workling
61
30
  uid = Workling::Remote.generate_uid(clazz, method)
62
31
  options[:uid] = uid if options.kind_of?(Hash) && !options[:uid]
63
32
  Workling.find(clazz, method) # this line raises a WorklingError if the method does not exist.
64
- dispatcher.run(clazz, method, options)
33
+ client.dispatch(clazz, method, options)
65
34
  uid
66
35
  end
67
36
 
@@ -6,36 +6,36 @@ module Workling
6
6
  module Return
7
7
  module Store
8
8
  mattr_accessor :instance
9
-
9
+
10
10
  # set a value in the store with the given key. delegates to the returnstore.
11
11
  def self.set(key, value)
12
12
  self.instance.set(key, value)
13
13
  end
14
-
14
+
15
15
  # get a value from the store. this should be destructive. delegates to the returnstore.
16
16
  def self.get(key)
17
17
  self.instance.get(key)
18
18
  end
19
-
19
+
20
20
  #
21
21
  # Base Class for Return Stores. Subclasses need to implement set and get.
22
22
  #
23
23
  class Base
24
-
24
+
25
25
  # set a value in the store with the given key.
26
26
  def set(key, value)
27
27
  raise NotImplementedError.new("set(key, value) not implemented in #{ self.class }")
28
28
  end
29
-
29
+
30
30
  # get a value from the store. this should be destructive.
31
31
  def get(key)
32
32
  raise NotImplementedError.new("get(key) not implemented in #{ self.class }")
33
33
  end
34
-
34
+
35
35
  def iterator(key)
36
36
  Workling::Return::Store::Iterator.new(key)
37
37
  end
38
-
38
+
39
39
  end
40
40
  end
41
41
  end
@@ -1,5 +1,3 @@
1
- require 'workling/return/store/base'
2
-
3
1
  #
4
2
  # Stores directly into memory. This is for tests only - not for production use. aight?
5
3
  #
@@ -1,6 +1,3 @@
1
- require 'workling/return/store/base'
2
- require 'workling/clients/memcache_queue_client'
3
-
4
1
  #
5
2
  # Recommended Return Store if you are using the Starling Runner. This
6
3
  # Simply sets and gets values against queues. 'key' is the name of the respective Queue.
@@ -9,22 +6,24 @@ module Workling
9
6
  module Return
10
7
  module Store
11
8
  class StarlingReturnStore < Base
9
+
12
10
  cattr_accessor :client
13
-
11
+
14
12
  def initialize
15
13
  self.client = Workling::Clients::MemcacheQueueClient.new
16
14
  self.client.connect
17
15
  end
18
-
16
+
19
17
  # set a value in the queue 'key'.
20
18
  def set(key, value)
21
- self.class.client.set(key, value)
19
+ self.client.set(key, value)
22
20
  end
23
-
21
+
24
22
  # get a value from starling queue 'key'.
25
23
  def get(key)
26
- self.class.client.get(key)
24
+ self.client.get(key)
27
25
  end
26
+
28
27
  end
29
28
  end
30
29
  end
@@ -5,12 +5,9 @@
5
5
  module Workling
6
6
  module Routing
7
7
  class Base < Hash
8
- # @@logger ||= ::RAILS_DEFAULT_LOGGER
9
- # cattr_accessor :logger
10
-
11
8
  def method_name
12
9
  raise Exception.new("method_name not implemented.")
13
10
  end
14
11
  end
15
12
  end
16
- end
13
+ end
@@ -1,5 +1,3 @@
1
- require 'workling/routing/base'
2
-
3
1
  #
4
2
  # Holds a hash of routes. Each Worker method has a corresponding hash entry after building.
5
3
  #
@@ -1,5 +1,3 @@
1
- require 'workling/routing/base'
2
-
3
1
  #
4
2
  # Holds a single route for a dedicated worker (if you want more worker processes, run more workers)
5
3
  #
@@ -24,8 +22,6 @@ module Workling
24
22
 
25
23
  # so routing[x] hash access works as expected
26
24
  self.default = @worker
27
-
28
- puts "** static routing: queue - #{@queue_name}, routing_key - #{@routing_key}, method - #{@method_name}, worker - #{@worker.class}"
29
25
  end
30
26
 
31
27
  # returns the worker method name, given the routing string.
@@ -1,15 +1,6 @@
1
1
  require 'optparse'
2
2
 
3
- class WorklingServer
4
- @@in_server_mode = false
5
- def self.in_server_mode
6
- @@in_server_mode
7
- end
8
-
9
- def self.in_server_mode=(server_mode)
10
- @@in_server_mode = server_mode
11
- end
12
-
3
+ class WorklingDaemon
13
4
 
14
5
  def self.partition_options(args)
15
6
  daemon = []
@@ -48,11 +39,13 @@ class WorklingServer
48
39
  opts = OptionParser.new do |opts|
49
40
  opts.banner = 'Usage: myapp [options]'
50
41
  opts.separator ''
51
- opts.on('-c', '--client CLIENT', String,"specify the client class") { |v| options[:client_class] = v }
52
- opts.on('-i', '--invoker INVOKER', String,"specify the invoker class") { |v| options[:invoker_class] = v }
53
- opts.on('-r', '--routing ROUTING', String,"specify the routing class") { |v| options[:routing_class] = v }
54
- opts.on('-l', '--load-path LOADPATH', String,"specify the load_path for the workers") { |v| options[:load_path] = v }
55
- opts.on('-e', '--environment ENVIRONMENT', String,"specify the environment") { |v| options[:rails_env] = v }
42
+ opts.on('-n', '--no_rails', "do not load Rails") { |v| options[:no_rails] = true }
43
+ opts.on('-c', '--client CLIENT', String, "specify the client class") { |v| options[:client_class] = v }
44
+ opts.on('-i', '--invoker INVOKER', String, "specify the invoker class") { |v| options[:invoker_class] = v }
45
+ opts.on('-r', '--routing ROUTING', String, "specify the routing class") { |v| options[:routing_class] = v }
46
+ opts.on('-l', '--load-path LOADPATH', String, "specify the load_path for the workers") { |v| options[:load_path] = v }
47
+ opts.on('-f', '--config-path CONFIGPATH', String, "specify the path to the workling.yml file") { |v| options[:config_path] = v }
48
+ opts.on('-e', '--environment ENVIRONMENT', String, "specify the environment") { |v| options[:rails_env] = v }
56
49
  end
57
50
  opts.parse!(partition_options(args).last)
58
51
  options
@@ -60,7 +53,7 @@ class WorklingServer
60
53
 
61
54
 
62
55
  def self.build_poller(options)
63
- require 'workling/remote'
56
+ require File.join(File.dirname(__FILE__), 'workling/remote')
64
57
  ["remote/invokers/*.rb", "routing/*.rb"].each do |pattern|
65
58
  Dir.glob(pattern).each do |f|
66
59
  require File.join(File.dirname(f), File.basename(f, ".rb"))
@@ -70,19 +63,25 @@ class WorklingServer
70
63
  routing_class = Object.module_eval("::#{options[:routing_class]}")
71
64
  client_class = Object.module_eval("::#{options[:client_class]}")
72
65
  invoker_class = Object.module_eval("::#{options[:invoker_class]}")
66
+
67
+ client_class.load
68
+
73
69
  invoker_class.new(routing_class.new, client_class)
74
70
  end
75
71
 
76
72
 
77
73
  def self.run(options)
78
- WorklingServer.in_server_mode = true
79
-
80
- ENV["RAILS_ENV"] = options[:rails_env]
81
- puts "=> Loading Rails with #{ENV["RAILS_ENV"]} environment..."
82
-
83
- require options[:rails_root] + '/config/environment'
74
+ if options[:no_rails]
75
+ # if rails is not booted we need to pull in the workling requires manually
76
+ require File.join(File.dirname(__FILE__), "workling")
77
+ else
78
+ ENV["RAILS_ENV"] = options[:rails_env]
79
+ puts "=> Loading Rails with #{ENV["RAILS_ENV"]} environment..."
80
+ require options[:rails_root] + '/config/environment'
81
+ end
84
82
 
85
83
  Workling.load_path = options[:load_path]
84
+ Workling.config_path = options[:config_path]
86
85
 
87
86
  Workling::Discovery.discover!
88
87
  Workling.config
@@ -93,16 +92,19 @@ class WorklingServer
93
92
  puts "** Starting #{ poller.class }..."
94
93
  puts '** Use CTRL-C to stop.'
95
94
 
96
- ActiveRecord::Base.logger = Workling::Base.logger
97
- ActionController::Base.logger = Workling::Base.logger
95
+ unless options[:no_rails]
96
+ ActiveRecord::Base.logger = Workling::Base.logger
97
+ ActionController::Base.logger = Workling::Base.logger
98
+ end
98
99
 
99
100
  trap(:INT) { poller.stop; exit }
100
101
 
101
102
  begin
102
103
  poller.listen
103
104
  ensure
104
- puts '** No Worklings found.' if Workling::Discovery.discovered.blank?
105
+ puts '** No Worklings found.' if Workling::Discovery.discovered.empty?
105
106
  puts '** Exiting'
106
107
  end
107
108
  end
109
+
108
110
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: derfred-workling
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.9.2
4
+ version: 0.4.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rany Keddo
@@ -26,51 +26,44 @@ files:
26
26
  - VERSION.yml
27
27
  - README.markdown
28
28
  - TODO.markdown
29
- - lib/cattr_accessor.rb
30
- - lib/mattr_accessor.rb
31
- - lib/rude_q/client.rb
29
+ - lib/extensions/cattr_accessor.rb
30
+ - lib/extensions/mattr_accessor.rb
32
31
  - lib/workling/base.rb
33
32
  - lib/workling/clients/amqp_client.rb
34
33
  - lib/workling/clients/amqp_exchange_client.rb
34
+ - lib/workling/clients/backgroundjob_client.rb
35
35
  - lib/workling/clients/base.rb
36
+ - lib/workling/clients/broker_base.rb
36
37
  - lib/workling/clients/memcache_queue_client.rb
38
+ - lib/workling/clients/memory_queue_client.rb
39
+ - lib/workling/clients/not_client.rb
40
+ - lib/workling/clients/not_remote_client.rb
41
+ - lib/workling/clients/spawn_client.rb
37
42
  - lib/workling/clients/sqs_client.rb
43
+ - lib/workling/clients/thread_client.rb
38
44
  - lib/workling/clients/xmpp_client.rb
39
45
  - lib/workling/discovery.rb
40
- - lib/workling/remote/invokers/amqp_single_subscriber.rb
41
- - lib/workling/remote/invokers/base.rb
42
- - lib/workling/remote/invokers/basic_poller.rb
43
- - lib/workling/remote/invokers/eventmachine_subscriber.rb
44
- - lib/workling/remote/invokers/looped_subscriber.rb
45
- - lib/workling/remote/invokers/thread_pool_poller.rb
46
- - lib/workling/remote/invokers/threaded_poller.rb
47
- - lib/workling/remote/runners/amqp_exchange_runner.rb
48
- - lib/workling/remote/runners/backgroundjob_runner.rb
49
- - lib/workling/remote/runners/base.rb
50
- - lib/workling/remote/runners/client_runner.rb
51
- - lib/workling/remote/runners/not_remote_runner.rb
52
- - lib/workling/remote/runners/not_runner.rb
53
- - lib/workling/remote/runners/rudeq_runner.rb
54
- - lib/workling/remote/runners/spawn_runner.rb
55
- - lib/workling/remote/runners/starling_runner.rb
46
+ - lib/workling/invokers/amqp_single_subscriber.rb
47
+ - lib/workling/invokers/base.rb
48
+ - lib/workling/invokers/basic_poller.rb
49
+ - lib/workling/invokers/eventmachine_subscriber.rb
50
+ - lib/workling/invokers/looped_subscriber.rb
51
+ - lib/workling/invokers/thread_pool_poller.rb
52
+ - lib/workling/invokers/threaded_poller.rb
56
53
  - lib/workling/remote.rb
57
54
  - lib/workling/return/store/base.rb
58
55
  - lib/workling/return/store/iterator.rb
59
56
  - lib/workling/return/store/memory_return_store.rb
60
- - lib/workling/return/store/rudeq_return_store.rb
61
57
  - lib/workling/return/store/starling_return_store.rb
62
58
  - lib/workling/routing/base.rb
63
59
  - lib/workling/routing/class_and_method_routing.rb
64
60
  - lib/workling/routing/static_routing.rb
65
- - lib/workling/rudeq/client.rb
66
- - lib/workling/rudeq/poller.rb
67
- - lib/workling/rudeq.rb
68
61
  - lib/workling.rb
69
- - lib/workling_server.rb
70
- - script/bj_invoker.rb
71
- - script/starling_status.rb
62
+ - lib/workling_daemon.rb
63
+ - contrib/bj_invoker.rb
64
+ - contrib/starling_status.rb
72
65
  has_rdoc: true
73
- homepage: http://github.com/elecnix/workling
66
+ homepage: http://github.com/derfred/workling
74
67
  post_install_message:
75
68
  rdoc_options:
76
69
  - --inline-source
data/lib/rude_q/client.rb DELETED
@@ -1,11 +0,0 @@
1
- #
2
- # A RudeQ client that behvaes somewhat like memcache-client
3
- #
4
- module RudeQ
5
- class Client
6
- def initialize(*args); super(); end
7
- def set(key, value); RudeQueue.set(key, value); end;
8
- def get(key); RudeQueue.get(key); end;
9
- def stats; ActiveRecord::Base.connection; end
10
- end
11
- end
@@ -1,45 +0,0 @@
1
- require 'eventmachine'
2
- require 'workling/remote/invokers/base'
3
-
4
- #
5
- # TODO - Subscribes a single worker to a single queue
6
- #
7
- module Workling
8
- module Remote
9
- module Invokers
10
- class AmqpSingleSubscriber < Workling::Remote::Invokers::Base
11
-
12
- def initialize(routing, client_class)
13
- super
14
- end
15
-
16
- #
17
- # Starts EM loop and sets up subscription callback for the worker
18
- # Create the queue and bind to exchange using the routing key
19
- #
20
- def listen
21
- EM.run do
22
- connect do
23
- queue_name = @routing.queue_for
24
- routing_key = @routing.routing_key_for
25
-
26
- # temp stuff to hook the queues and exchanges up
27
- # wildcard routing - # (match all)
28
- exch = MQ.topic
29
- q = MQ.queue(queue_name)
30
- q.bind(exch, :key => routing_key)
31
-
32
- @client.subscribe(queue_name) do |args|
33
- run(queue_name, args)
34
- end
35
- end
36
- end
37
- end
38
-
39
- def stop
40
- EM.stop if EM.reactor_running?
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,124 +0,0 @@
1
- #
2
- # Invokers are responsible for
3
- #
4
- # 1. grabbing work off a job broker (such as a starling or rabbitmq server).
5
- # 2. routing (mapping) that work onto the correct worker method.
6
- # 3. invoking the worker method, passing any arguments that came off the broker.
7
- #
8
- # Invokers should implement their own concurrency strategies. For example,
9
- # The there is a ThreadedPoller which starts a thread for each Worker class.
10
- #
11
- # This base Invoker class defines the methods an Invoker needs to implement.
12
- #
13
- module Workling
14
- module Remote
15
- module Invokers
16
- class Base
17
-
18
- attr_accessor :sleep_time, :reset_time
19
-
20
- #
21
- # call up with super in the subclass constructor.
22
- #
23
- def initialize(routing, client_class)
24
- @routing = routing
25
- @client_class = client_class
26
- @sleep_time = Workling.config[:sleep_time] || 2
27
- @reset_time = Workling.config[:reset_time] || 30
28
- @@mutex ||= Mutex.new
29
- end
30
-
31
- #
32
- # Starts main Invoker Loop. The invoker runs until stop() is called.
33
- #
34
- def listen
35
- raise NotImplementedError.new("Implement listen() in your Invoker. ")
36
- end
37
-
38
- #
39
- # Gracefully stops the Invoker. The currently executing Jobs should be allowed
40
- # to finish.
41
- #
42
- def stop
43
- raise NotImplementedError.new("Implement stop() in your Invoker. ")
44
- end
45
-
46
- #
47
- # Runs the worker method, given
48
- #
49
- # type: the worker route
50
- # args: the arguments to be passed into the worker method.
51
- #
52
- def run(type, args)
53
- worker = @routing[type]
54
- method = @routing.method_name(type)
55
- worker.dispatch_to_worker_method(method, args)
56
- end
57
-
58
- # returns the Workling::Base.logger
59
- def logger; Workling::Base.logger; end
60
-
61
- protected
62
-
63
- # handle opening and closing of client. pass code block to this method.
64
- def connect
65
- @client = @client_class.new
66
- @client.connect
67
-
68
- begin
69
- yield
70
- ensure
71
- @client.close
72
- ActiveRecord::Base.verify_active_connections!
73
- end
74
- end
75
-
76
- #
77
- # Loops through the available routes, yielding for each route.
78
- # This continues until @shutdown is set on this instance.
79
- #
80
- def loop_routes
81
- while(!@shutdown) do
82
- ensure_activerecord_connection
83
-
84
- routes.each do |route|
85
- break if @shutdown
86
- yield route
87
- end
88
-
89
- sleep self.sleep_time
90
- end
91
- end
92
-
93
- #
94
- # Returns the complete set of active routes
95
- #
96
- def routes
97
- @active_routes ||= Workling::Discovery.discovered.map { |clazz| @routing.queue_names_routing_class(clazz) }.flatten
98
- end
99
-
100
- # Thanks for this Brent!
101
- #
102
- # ...Just a heads up, due to how rails’ MySQL adapter handles this
103
- # call ‘ActiveRecord::Base.connection.active?’, you’ll need
104
- # to wrap the code that checks for a connection in in a mutex.
105
- #
106
- # ....I noticed this while working with a multi-core machine that
107
- # was spawning multiple workling threads. Some of my workling
108
- # threads would hit serious issues at this block of code without
109
- # the mutex.
110
- #
111
- def ensure_activerecord_connection
112
- @@mutex.synchronize do
113
- unless ActiveRecord::Base.connection.active? # Keep MySQL connection alive
114
- unless ActiveRecord::Base.connection.reconnect!
115
- logger.fatal("Failed - Database not available!")
116
- break
117
- end
118
- end
119
- end
120
- end
121
- end
122
- end
123
- end
124
- end