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
data/bin/workling_client CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'rubygems'
3
3
  require 'daemons'
4
- require 'workling_server'
4
+ require File.join(File.dirname(__FILE__), '../lib/workling_daemon')
5
5
 
6
6
  daemon_options = {
7
7
  :app_name => "workling",
@@ -11,18 +11,20 @@ daemon_options = {
11
11
  :multiple => false,
12
12
  :backtrace => true,
13
13
  :monitor => false
14
- }.merge(WorklingServer.parse_daemon_options(ARGV))
14
+ }.merge(WorklingDaemon.parse_daemon_options(ARGV))
15
15
 
16
16
  workling_options = {
17
17
  :client_class => "Workling::Clients::MemcacheQueueClient",
18
18
  :invoker_class => "Workling::Remote::Invokers::ThreadedPoller",
19
19
  :routing_class => "Workling::Routing::ClassAndMethodRouting",
20
20
  :rails_root => Dir.pwd,
21
- :load_path => [ 'app/workers/**/*.rb' ],
22
- :rails_env => (ENV['RAILS_ENV'] || "development").dup
23
- }.merge(WorklingServer.parse_workling_options(ARGV))
21
+ :load_path => ['app/workers/**/*.rb'],
22
+ :config_path => "config/workling.yml",
23
+ :rails_env => (ENV['RAILS_ENV'] || "development").dup,
24
+ :no_rails => false
25
+ }.merge(WorklingDaemon.parse_workling_options(ARGV))
24
26
 
25
27
  Daemons.run_proc(daemon_options[:app_name], daemon_options) do
26
28
  Dir.chdir(workling_options[:rails_root])
27
- WorklingServer.run(workling_options)
28
- end
29
+ WorklingDaemon.run(workling_options)
30
+ end
File without changes
File without changes
data/lib/workling.rb CHANGED
@@ -1,8 +1,12 @@
1
1
  #
2
2
  # I can haz am in your Workling are belong to us!
3
3
  #
4
- require 'mattr_accessor' unless Module.respond_to?(:mattr_accessor)
5
- require 'cattr_accessor' unless Class.respond_to?(:cattr_accessor)
4
+ def require_in_tree(name)
5
+ require File.join(File.dirname(__FILE__), name)
6
+ end
7
+
8
+ require_in_tree 'extensions/mattr_accessor' unless Module.respond_to?(:mattr_accessor)
9
+ require_in_tree 'extensions/cattr_accessor' unless Class.respond_to?(:cattr_accessor)
6
10
 
7
11
  gem 'activesupport'
8
12
  require 'active_support/inflector'
@@ -51,30 +55,72 @@ module Workling
51
55
  mattr_accessor :load_path
52
56
  @@load_path = [ File.expand_path(path('app', 'workers')) ]
53
57
 
54
- VERSION = "0.4.9"
58
+ VERSION = "0.4.9" unless defined?(VERSION)
55
59
 
56
60
  #
57
- # determine the runner to use if nothing is specifically set. workling will try to detect
61
+ # determine the client to use if nothing is specifically set. workling will try to detect
58
62
  # starling, spawn, or bj, in that order. if none of these are found, notremoterunner will
59
63
  # be used.
60
64
  #
61
- # this can be overridden by setting Workling::Remote.dispatcher, eg:
62
- # Workling::Remote.dispatcher = Workling::Remote::Runners::StarlingRunner.new
63
- #
64
- def self.default_runner
65
+ def self.select_and_build_default_client
65
66
  if env == "test"
66
- Workling::Remote::Runners::NotRemoteRunner.new
67
- elsif starling_installed?
68
- Workling::Remote::Runners::StarlingRunner.new
69
- elsif spawn_installed?
70
- Workling::Remote::Runners::SpawnRunner.new
71
- elsif bj_installed?
72
- Workling::Remote::Runners::BackgroundjobRunner.new
67
+ Workling::Clients::NotRemoteClient.new
68
+ elsif Workling::Clients::SpawnClient.installed?
69
+ Workling::Clients::SpawnClient.new
70
+ elsif Workling::Clients::BackgroundjobClient.installed?
71
+ Workling::Clients::BackgroundjobClient.new
73
72
  else
74
- Workling::Remote::Runners::NotRemoteRunner.new
73
+ Workling::Clients::NotRemoteClient.new
75
74
  end
76
75
  end
77
-
76
+
77
+ #
78
+ # this will build the client to use for job dispatching and retrieval
79
+ # The look up does the following:
80
+ # 1. if Workling::Remote.client is set explicitly then that client is used
81
+ # 2. if workling.yml (or whatever file is used) contains a client section then that is used
82
+ # 3. otherwise the default client is built using the Workling.select_and_build_default_client method
83
+ #
84
+ def self.select_and_build_client
85
+ case(Workling.config[:client])
86
+ when 'amqp'
87
+ Workling::Clients::AmqpClient
88
+
89
+ when 'amqp_exchange'
90
+ Workling::Clients::AmqpExchangeClient
91
+
92
+ when 'memcache', 'starling'
93
+ Workling::Clients::MemcacheQueueClient
94
+
95
+ when 'memory_queue' # this one is pretty useles...
96
+ Workling::Clients::MemoryQueueClient
97
+
98
+ when 'sqs'
99
+ Workling::Clients::SqsClient
100
+
101
+ when 'xmpp'
102
+ Workling::Clients::XmppClient
103
+
104
+ when 'backgroundjob'
105
+ Workling::Clients::BackgroundjobClient
106
+
107
+ when 'not_remote'
108
+ Workling::Clients::NotRemoteClient
109
+
110
+ when 'not'
111
+ Workling::Clients::NotClient
112
+
113
+ when 'spawn'
114
+ Workling::Clients::SpawnClient
115
+
116
+ when 'thread'
117
+ Workling::Clients::ThreadClient
118
+
119
+ else
120
+ select_and_build_default_client
121
+ end
122
+ end
123
+
78
124
  #
79
125
  # gets the worker instance, given a class. the optional method argument will cause an
80
126
  # exception to be raised if the worker instance does not respoind to said method.
@@ -88,108 +134,66 @@ module Workling
88
134
  raise_not_found(clazz, method) if method && !inst.respond_to?(method)
89
135
  inst
90
136
  end
91
-
137
+
92
138
  # returns Workling::Return::Store.instance.
93
139
  def self.return
94
140
  Workling::Return::Store.instance
95
141
  end
96
142
 
97
- # is spawn installed?
98
- def self.spawn_installed?
99
- begin
100
- require 'spawn'
101
- rescue LoadError
102
- end
103
-
104
- Object.const_defined? "Spawn"
105
- end
106
-
107
- # is starling installed?
108
- def self.starling_installed?
109
- begin
110
- require 'starling'
111
- rescue LoadError
112
- end
113
-
114
- Object.const_defined? "Starling"
115
- end
116
-
117
- # is bj installed?
118
- def self.bj_installed?
119
- Object.const_defined? "Bj"
120
- end
121
-
122
- # Attempts to load the memcache-client gem
123
- def self.try_load_a_memcache_client
124
- begin
125
- gem 'memcache-client'
126
- require 'memcache'
127
- rescue Gem::LoadError
128
- Workling::Base.logger.info "WORKLING: couldn't find memcache-client. Install: \"gem install memcache-client\". "
129
- end
130
- end
131
-
132
- # attempts to load amqp and writes out descriptive error message if not present
133
- def self.try_load_an_amqp_client
134
- begin
135
- require 'mq'
136
- rescue Exception => e
137
- raise WorklingError.new(
138
- "WORKLING: couldn't find the ruby amqp client - you need it for the amqp runner. " \
139
- "Install from github: gem sources -a http://gems.github.com/ && sudo gem install tmm1-amqp "
140
- )
141
- end
142
- end
143
-
144
- # attempts to load xmpp4r library and writes out descriptive error message if not present
145
- def self.try_load_xmpp4r
146
- begin
147
- gem "xmpp4r"
148
- require 'xmpp4r'
149
- require "xmpp4r/pubsub"
150
- require "xmpp4r/pubsub/helper/servicehelper.rb"
151
- require "xmpp4r/pubsub/helper/nodebrowser.rb"
152
- require "xmpp4r/pubsub/helper/nodehelper.rb"
153
- rescue Exception => e
154
- raise WorklingError.new("Couldnt load the XMPP library. check that you have the xmpp4r gem installed")
155
- end
156
- end
157
-
158
-
159
143
  #
160
144
  # returns a config hash. reads ./config/workling.yml
161
145
  #
146
+ mattr_writer :config
162
147
  def self.config
163
148
  return @@config if defined?(@@config) && @@config
164
149
 
165
- config_path = File.join(RAILS_ROOT, 'config', 'workling.yml')
166
150
  return nil unless File.exists?(config_path)
167
-
168
- @@config ||= YAML.load_file(config_path)[RAILS_ENV || 'development'].symbolize_keys
151
+
152
+ @@config ||= YAML.load_file(config_path)[env || 'development'].symbolize_keys
169
153
  @@config[:memcache_options].symbolize_keys! if @@config[:memcache_options]
170
154
  @@config
171
155
  end
172
-
156
+
157
+ mattr_writer :config_path
158
+ def self.config_path
159
+ return @@config_path if defined?(@@config_path) && @@config_path
160
+ @@config_path = File.join(RAILS_ROOT, 'config', 'workling.yml')
161
+ end
162
+
173
163
  #
174
164
  # Raises exceptions thrown inside of the worker. normally, these are logged to
175
165
  # logger.error. it's easy to miss these log calls while developing, though.
176
166
  #
177
- mattr_accessor :raise_exceptions
178
- @@raise_exceptions = (RAILS_ENV == "test" || RAILS_ENV == "development")
179
-
167
+ mattr_writer :raise_exceptions
168
+ def raise_exceptions
169
+ return @@raise_exceptions if defined?(@@raise_exceptions)
170
+ @@raise_exceptions = (RAILS_ENV == "test" || RAILS_ENV == "development")
171
+ end
172
+
180
173
  def self.raise_exceptions?
181
174
  @@raise_exceptions
182
175
  end
183
-
176
+
184
177
  private
185
178
  def self.raise_not_found(clazz, method)
186
179
  raise Workling::WorklingNotFoundError.new("could not find #{ clazz }:#{ method } workling. ")
187
180
  end
181
+
188
182
  end
189
183
 
190
- require "workling/discovery"
191
- require "workling/base"
192
- require "workling/remote"
193
- require "workling/return/store/base"
194
- require "workling/return/store/memory_return_store"
195
- require "workling/return/store/starling_return_store"
184
+ require_in_tree "workling/discovery"
185
+ require_in_tree "workling/base"
186
+ require_in_tree "workling/remote"
187
+
188
+ require_in_tree "workling/clients/base"
189
+ require_in_tree "workling/clients/broker_base"
190
+ require_in_tree "workling/invokers/base"
191
+ require_in_tree "workling/return/store/base"
192
+ require_in_tree "workling/routing/base"
193
+
194
+ # load all possible extension classes
195
+ ["clients", "invokers", "return/store", "routing"].each do |e_dirs|
196
+ Dir.glob(File.join(File.dirname(__FILE__), "workling", e_dirs, "*.rb")).each do |rb_file|
197
+ require File.join(File.dirname(rb_file), File.basename(rb_file, ".rb"))
198
+ end
199
+ end
data/lib/workling/base.rb CHANGED
@@ -1,5 +1,3 @@
1
- #require 'struct'
2
-
3
1
  #
4
2
  # All worker classes must inherit from this class, and be saved in app/workers.
5
3
  #
@@ -16,9 +14,14 @@
16
14
  #
17
15
  module Workling
18
16
  class Base
17
+
19
18
  cattr_writer :logger
20
19
  def self.logger
21
- @@logger ||= ::RAILS_DEFAULT_LOGGER
20
+ @@logger ||= defined?(RAILS_DEFAULT_LOGGER) ? ::RAILS_DEFAULT_LOGGER : Logger.new($stdout)
21
+ end
22
+
23
+ def logger
24
+ self.class.logger
22
25
  end
23
26
 
24
27
  cattr_accessor :exposed_methods
@@ -83,7 +86,6 @@ module Workling
83
86
  raise e
84
87
  rescue Exception => e
85
88
  notify_exception e, method, options
86
- on_error(e) if respond_to?(:on_error)
87
89
 
88
90
  # reraise after logging. the exception really can't go anywhere in many cases. (spawn traps the exception)
89
91
  raise e if Workling.raise_exceptions?
@@ -103,13 +105,6 @@ module Workling
103
105
  super
104
106
  end
105
107
  end
106
-
107
- def self.logger
108
- @logger ||= defined?(RAILS_DEFAULT_LOGGER) ? ::RAILS_DEFAULT_LOGGER : Logger.new($stdout)
109
- end
110
108
 
111
- def logger
112
- self.class.logger
113
- end
114
109
  end
115
110
  end
@@ -1,13 +1,21 @@
1
- require 'workling/clients/base'
2
- Workling.try_load_an_amqp_client
3
-
4
1
  #
5
2
  # An Ampq client
6
3
  #
7
4
  module Workling
8
5
  module Clients
9
- class AmqpClient < Workling::Clients::Base
10
-
6
+ class AmqpClient < Workling::Clients::BrokerBase
7
+
8
+ def self.load
9
+ begin
10
+ require 'mq'
11
+ rescue Exception => e
12
+ raise WorklingError.new(
13
+ "WORKLING: couldn't find the ruby amqp client - you need it for the amqp runner. " \
14
+ "Install from github: gem sources -a http://gems.github.com/ && sudo gem install tmm1-amqp "
15
+ )
16
+ end
17
+ end
18
+
11
19
  # starts the client.
12
20
  def connect
13
21
  begin
@@ -1,13 +1,21 @@
1
- require 'workling/clients/base'
2
- Workling.try_load_an_amqp_client
3
-
4
1
  #
5
2
  # An Ampq client
6
3
  #
7
4
  module Workling
8
5
  module Clients
9
- class AmqpExchangeClient < Workling::Clients::Base
10
-
6
+ class AmqpExchangeClient < Workling::Clients::BrokerBase
7
+
8
+ def self.load
9
+ begin
10
+ require 'mq'
11
+ rescue Exception => e
12
+ raise WorklingError.new(
13
+ "WORKLING: couldn't find the ruby amqp client - you need it for the amqp runner. " \
14
+ "Install from github: gem sources -a http://gems.github.com/ && sudo gem install tmm1-amqp "
15
+ )
16
+ end
17
+ end
18
+
11
19
  # starts the client.
12
20
  def connect
13
21
  begin
@@ -16,22 +24,19 @@ module Workling
16
24
  raise WorklingError.new("couldn't start amq client. if you're running this in a server environment, then make sure the server is evented (ie use thin or evented mongrel, not normal mongrel.)")
17
25
  end
18
26
  end
19
-
27
+
20
28
  # no need for explicit closing. when the event loop
21
29
  # terminates, the connection is closed anyway.
22
30
  def close; true; end
23
-
31
+
24
32
  # subscribe to a queue
25
33
  def subscribe(key)
26
34
  @amq.queue(key).subscribe do |header, body|
27
-
28
- puts "***** received msg with header - #{header.inspect}"
29
-
30
35
  value = YAML.load(body)
31
36
  yield value
32
37
  end
33
38
  end
34
-
39
+
35
40
  # request and retrieve work
36
41
  def retrieve(key)
37
42
  @amq.queue(key)
@@ -40,11 +45,14 @@ module Workling
40
45
  # publish message to exchange
41
46
  # using the specified routing key
42
47
  def request(exchange_name, value)
48
+ exchange_name = "amq.topic"
49
+
43
50
  key = value.delete(:routing_key)
44
51
  msg = YAML.dump(value)
45
52
  exchange = @amq.topic(exchange_name)
46
53
  exchange.publish(msg, :routing_key => key)
47
54
  end
55
+
48
56
  end
49
57
  end
50
58
  end
@@ -0,0 +1,25 @@
1
+ module Workling
2
+ module Clients
3
+ class BackgroundjobClient < Workling::Clients::Base
4
+
5
+ def self.installed?
6
+ Object.const_defined? "Bj"
7
+ end
8
+
9
+ # passes the job to bj by serializing the options to xml and passing them to
10
+ # ./script/bj_invoker.rb, which in turn routes the deserialized args to the
11
+ # appropriate worker.
12
+ def dispatch(clazz, method, options = {})
13
+ stdin = Workling::Remote.routing.queue_for(clazz, method) +
14
+ " " +
15
+ options.to_xml(:indent => 0, :skip_instruct => true)
16
+
17
+ Bj.submit "./script/runner ./script/bj_invoker.rb",
18
+ :stdin => stdin
19
+
20
+ return nil # that means nothing!
21
+ end
22
+
23
+ end
24
+ end
25
+ end