derfred-workling 0.4.9.5 → 0.4.9.6
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/workling_client +3 -4
- data/lib/workling.rb +56 -45
- data/lib/workling/clients/amqp_client.rb +11 -6
- data/lib/workling/clients/memcache_queue_client.rb +2 -1
- data/lib/workling/remote.rb +2 -2
- data/lib/workling_daemon.rb +31 -30
- metadata +1 -1
data/bin/workling_client
CHANGED
@@ -14,12 +14,11 @@ daemon_options = {
|
|
14
14
|
}.merge(WorklingDaemon.parse_daemon_options(ARGV))
|
15
15
|
|
16
16
|
workling_options = {
|
17
|
-
:client_class => "
|
18
|
-
:invoker_class => "
|
19
|
-
:routing_class => "
|
17
|
+
:client_class => "memcache_queue",
|
18
|
+
:invoker_class => "threaded_poller",
|
19
|
+
:routing_class => "class_and_method",
|
20
20
|
:rails_root => Dir.pwd,
|
21
21
|
:load_path => ['app/workers/**/*.rb'],
|
22
|
-
:config_path => "config/workling.yml",
|
23
22
|
:rails_env => (ENV['RAILS_ENV'] || "development").dup,
|
24
23
|
:no_rails => false
|
25
24
|
}.merge(WorklingDaemon.parse_workling_options(ARGV))
|
data/lib/workling.rb
CHANGED
@@ -27,7 +27,6 @@ module Workling
|
|
27
27
|
super "config/workling.yml configured to connect to queue server on #{ Workling.config[:listens_on] } for this environment. could not connect to queue server on this host:port. for starling users: pass starling the port with -p flag when starting it. If you don't want to use Starling, then explicitly set Workling::Remote.dispatcher (see README for an example)"
|
28
28
|
end
|
29
29
|
end
|
30
|
-
|
31
30
|
class ConfigurationError < WorklingError
|
32
31
|
def initialize
|
33
32
|
super File.exist?(Workling.path('config', 'starling.yml')) ?
|
@@ -35,7 +34,7 @@ module Workling
|
|
35
34
|
"config/workling.yml could not be loaded. check out README.markdown to see what this file should contain. "
|
36
35
|
end
|
37
36
|
end
|
38
|
-
|
37
|
+
|
39
38
|
def self.path(*args)
|
40
39
|
if defined?(RAILS_ROOT)
|
41
40
|
File.join(RAILS_ROOT, *args)
|
@@ -62,18 +61,42 @@ module Workling
|
|
62
61
|
# starling, spawn, or bj, in that order. if none of these are found, notremoterunner will
|
63
62
|
# be used.
|
64
63
|
#
|
65
|
-
def self.
|
64
|
+
def self.select_default_client
|
66
65
|
if env == "test"
|
67
|
-
Workling::Clients::NotRemoteClient
|
66
|
+
Workling::Clients::NotRemoteClient
|
68
67
|
elsif Workling::Clients::SpawnClient.installed?
|
69
|
-
Workling::Clients::SpawnClient
|
68
|
+
Workling::Clients::SpawnClient
|
70
69
|
elsif Workling::Clients::BackgroundjobClient.installed?
|
71
|
-
Workling::Clients::BackgroundjobClient
|
70
|
+
Workling::Clients::BackgroundjobClient
|
72
71
|
else
|
73
|
-
Workling::Clients::NotRemoteClient
|
72
|
+
Workling::Clients::NotRemoteClient
|
74
73
|
end
|
75
74
|
end
|
76
75
|
|
76
|
+
def self.clients
|
77
|
+
{
|
78
|
+
'amqp' => Workling::Clients::AmqpClient,
|
79
|
+
'amqp_exchange' => Workling::Clients::AmqpExchangeClient,
|
80
|
+
'memcache' => Workling::Clients::MemcacheQueueClient,
|
81
|
+
'starling' => Workling::Clients::MemcacheQueueClient,
|
82
|
+
'memory_queue' => Workling::Clients::MemoryQueueClient,
|
83
|
+
'sqs' => Workling::Clients::SqsClient,
|
84
|
+
'xmpp' => Workling::Clients::XmppClient,
|
85
|
+
'backgroundjob' => Workling::Clients::BackgroundjobClient,
|
86
|
+
'not_remote' => Workling::Clients::NotRemoteClient,
|
87
|
+
'not' => Workling::Clients::NotClient,
|
88
|
+
'spawn' => Workling::Clients::SpawnClient,
|
89
|
+
'thread' => Workling::Clients::ThreadClient,
|
90
|
+
'rudeq' => Workling::Clients::RudeQClient
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.select_client
|
95
|
+
client_class = clients[Workling.config[:client]] || select_default_client
|
96
|
+
client_class.load
|
97
|
+
client_class
|
98
|
+
end
|
99
|
+
|
77
100
|
#
|
78
101
|
# this will build the client to use for job dispatching and retrieval
|
79
102
|
# The look up does the following:
|
@@ -82,46 +105,34 @@ module Workling
|
|
82
105
|
# 3. otherwise the default client is built using the Workling.select_and_build_default_client method
|
83
106
|
#
|
84
107
|
def self.select_and_build_client
|
85
|
-
|
86
|
-
|
87
|
-
Workling::Clients::AmqpClient.new
|
88
|
-
|
89
|
-
when 'amqp_exchange'
|
90
|
-
Workling::Clients::AmqpExchangeClient.new
|
91
|
-
|
92
|
-
when 'memcache', 'starling'
|
93
|
-
Workling::Clients::MemcacheQueueClient.new
|
94
|
-
|
95
|
-
when 'memory_queue' # this one is pretty useles...
|
96
|
-
Workling::Clients::MemoryQueueClient.new
|
97
|
-
|
98
|
-
when 'sqs'
|
99
|
-
Workling::Clients::SqsClient.new
|
100
|
-
|
101
|
-
when 'xmpp'
|
102
|
-
Workling::Clients::XmppClient.new
|
103
|
-
|
104
|
-
when 'backgroundjob'
|
105
|
-
Workling::Clients::BackgroundjobClient.new
|
106
|
-
|
107
|
-
when 'not_remote'
|
108
|
-
Workling::Clients::NotRemoteClient.new
|
109
|
-
|
110
|
-
when 'not'
|
111
|
-
Workling::Clients::NotClient.new
|
112
|
-
|
113
|
-
when 'spawn'
|
114
|
-
Workling::Clients::SpawnClient.new
|
115
|
-
|
116
|
-
when 'thread'
|
117
|
-
Workling::Clients::ThreadClient.new
|
108
|
+
select_client.new
|
109
|
+
end
|
118
110
|
|
119
|
-
|
120
|
-
|
111
|
+
#
|
112
|
+
# this will select the routing class
|
113
|
+
#
|
114
|
+
def self.select_and_build_routing
|
115
|
+
routing_class = {
|
116
|
+
'class_and_method' => Workling::Routing::ClassAndMethodRouting,
|
117
|
+
'static' => Workling::Routing::StaticRouting
|
118
|
+
}[Workling.config[:routing]] || Workling::Routing::ClassAndMethodRouting
|
119
|
+
routing_class.new
|
120
|
+
end
|
121
121
|
|
122
|
-
|
123
|
-
|
124
|
-
|
122
|
+
#
|
123
|
+
# this will build the invoker which will run the daemon
|
124
|
+
#
|
125
|
+
def self.select_and_build_invoker
|
126
|
+
invoker_class = {
|
127
|
+
'basic_poller' => Workling::Invokers::BasicPoller,
|
128
|
+
'thread_pool_poller' => Workling::Invokers::ThreadPoolPoller,
|
129
|
+
'threaded_poller' => Workling::Invokers::ThreadedPoller,
|
130
|
+
|
131
|
+
'eventmachine_subscriber' => Workling::Invokers::EventmachineSubscriber,
|
132
|
+
'looped_subscriber' => Workling::Invokers::LoopedSubscriber,
|
133
|
+
'amqp_single_subscriber' => Workling::Invokers::AmqpSingleSubscriber,
|
134
|
+
}[Workling.config[:invoker]] || Workling::Invokers::BasicPoller
|
135
|
+
invoker_class.new(select_and_build_routing, select_client)
|
125
136
|
end
|
126
137
|
|
127
138
|
#
|
@@ -25,22 +25,27 @@ module Workling
|
|
25
25
|
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.)")
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
# no need for explicit closing. when the event loop
|
30
30
|
# terminates, the connection is closed anyway.
|
31
31
|
def close; true; end
|
32
|
-
|
32
|
+
|
33
33
|
# subscribe to a queue
|
34
34
|
def subscribe(key)
|
35
|
-
@amq.queue(key).subscribe do |value|
|
35
|
+
@amq.queue(queue_for(key)).subscribe do |value|
|
36
36
|
data = Marshal.load(value) rescue value
|
37
37
|
yield data
|
38
38
|
end
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
# request and retrieve work
|
42
|
-
def retrieve(key); @amq.queue(key); end
|
43
|
-
def request(key, value); @amq.queue(key).publish(Marshal.dump(value)); end
|
42
|
+
def retrieve(key); @amq.queue(queue_for(key)); end
|
43
|
+
def request(key, value); @amq.queue(queue_for(key)).publish(Marshal.dump(value)); end
|
44
|
+
|
45
|
+
private
|
46
|
+
def queue_for(key)
|
47
|
+
"#{Workling.config[:prefix]}#{key}"
|
48
|
+
end
|
44
49
|
end
|
45
50
|
end
|
46
51
|
end
|
@@ -44,7 +44,8 @@ module Workling
|
|
44
44
|
# to queueserver.
|
45
45
|
#
|
46
46
|
def connect
|
47
|
-
|
47
|
+
listens_on = Workling.config[:listens_on] || "localhost:22122"
|
48
|
+
@queueserver_urls = listens_on.split(',').map { |url| url ? url.strip : url }
|
48
49
|
options = [@queueserver_urls, Workling.config[:memcache_options]].compact
|
49
50
|
self.connection = ::MemCache.new(*options)
|
50
51
|
|
data/lib/workling/remote.rb
CHANGED
@@ -23,13 +23,13 @@ module Workling
|
|
23
23
|
uid = ::Digest::MD5.hexdigest("#{ clazz }:#{ method }:#{ rand(1 << 64) }:#{ Time.now }")
|
24
24
|
"#{ clazz.to_s.tableize }/#{ method }/#{ uid }".split("/").join(":")
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
# dispatches to a workling. writes the :uid for this work into the options hash, so make
|
28
28
|
# sure you pass in a hash if you want write to a return store in your workling.
|
29
29
|
def self.run(clazz, method, options = {})
|
30
30
|
uid = Workling::Remote.generate_uid(clazz, method)
|
31
31
|
options[:uid] = uid if options.kind_of?(Hash) && !options[:uid]
|
32
|
-
Workling.find(clazz, method) # this line raises a WorklingError if the method does not exist.
|
32
|
+
Workling.find(clazz, method) # this line raises a WorklingError if the method does not exist.
|
33
33
|
client.dispatch(clazz, method, options)
|
34
34
|
uid
|
35
35
|
end
|
data/lib/workling_daemon.rb
CHANGED
@@ -40,37 +40,41 @@ class WorklingDaemon
|
|
40
40
|
opts.banner = 'Usage: myapp [options]'
|
41
41
|
opts.separator ''
|
42
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[:
|
44
|
-
opts.on('-i', '--invoker INVOKER', String, "specify the invoker class") { |v| options[:
|
45
|
-
opts.on('-r', '--routing ROUTING', String, "specify the routing class") { |v| options[:
|
43
|
+
opts.on('-c', '--client CLIENT', String, "specify the client class") { |v| options[:client] = v }
|
44
|
+
opts.on('-i', '--invoker INVOKER', String, "specify the invoker class") { |v| options[:invoker] = v }
|
45
|
+
opts.on('-r', '--routing ROUTING', String, "specify the routing class") { |v| options[:routing] = v }
|
46
46
|
opts.on('-l', '--load-path LOADPATH', String, "specify the load_path for the workers") { |v| options[:load_path] = v }
|
47
47
|
opts.on('-f', '--config-path CONFIGPATH', String, "specify the path to the workling.yml file") { |v| options[:config_path] = v }
|
48
48
|
opts.on('-e', '--environment ENVIRONMENT', String, "specify the environment") { |v| options[:rails_env] = v }
|
49
|
+
opts.on('-p', '--prefix PREFIX', String, "specify the prefix for queues") { |v| options[:prefix] = v }
|
49
50
|
end
|
50
51
|
opts.parse!(partition_options(args).last)
|
51
52
|
options
|
52
53
|
end
|
53
54
|
|
55
|
+
def self.extract_options(options)
|
56
|
+
result = {}
|
57
|
+
result[:client] = options[:client] if options[:client]
|
58
|
+
result[:routing] = options[:routing] if options[:routing]
|
59
|
+
result[:invoker] = options[:invoker] if options[:invoker]
|
60
|
+
result
|
61
|
+
end
|
54
62
|
|
55
|
-
def self.
|
56
|
-
|
57
|
-
|
58
|
-
Dir.glob(pattern).each do |f|
|
59
|
-
require File.join(File.dirname(f), File.basename(f, ".rb"))
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
routing_class = Object.module_eval("::#{options[:routing_class]}")
|
64
|
-
client_class = Object.module_eval("::#{options[:client_class]}")
|
65
|
-
invoker_class = Object.module_eval("::#{options[:invoker_class]}")
|
63
|
+
def self.initialize_workling(options)
|
64
|
+
Workling.load_path = options[:load_path] if options[:load_path]
|
65
|
+
Workling::Discovery.discover!
|
66
66
|
|
67
|
-
|
67
|
+
if options[:config_path]
|
68
|
+
Workling.config_path = options[:config_path]
|
69
|
+
Workling.config
|
70
|
+
else
|
71
|
+
Workling.config = extract_options options
|
72
|
+
end
|
68
73
|
|
69
|
-
|
74
|
+
Workling.select_and_build_invoker
|
70
75
|
end
|
71
76
|
|
72
|
-
|
73
|
-
def self.run(options)
|
77
|
+
def self.boot_with(options)
|
74
78
|
if options[:no_rails]
|
75
79
|
# if rails is not booted we need to pull in the workling requires manually
|
76
80
|
require File.join(File.dirname(__FILE__), "workling")
|
@@ -78,25 +82,22 @@ class WorklingDaemon
|
|
78
82
|
ENV["RAILS_ENV"] = options[:rails_env]
|
79
83
|
puts "=> Loading Rails with #{ENV["RAILS_ENV"]} environment..."
|
80
84
|
require options[:rails_root] + '/config/environment'
|
81
|
-
end
|
82
85
|
|
83
|
-
|
84
|
-
|
86
|
+
ActiveRecord::Base.logger = Workling::Base.logger
|
87
|
+
ActionController::Base.logger = Workling::Base.logger
|
88
|
+
|
89
|
+
puts '** Rails loaded.'
|
90
|
+
end
|
91
|
+
end
|
85
92
|
|
86
|
-
Workling::Discovery.discover!
|
87
|
-
Workling.config
|
88
93
|
|
89
|
-
|
94
|
+
def self.run(options)
|
95
|
+
boot_with options
|
96
|
+
poller = initialize_workling(options)
|
90
97
|
|
91
|
-
puts '** Rails loaded.'
|
92
98
|
puts "** Starting #{ poller.class }..."
|
93
99
|
puts '** Use CTRL-C to stop.'
|
94
100
|
|
95
|
-
unless options[:no_rails]
|
96
|
-
ActiveRecord::Base.logger = Workling::Base.logger
|
97
|
-
ActionController::Base.logger = Workling::Base.logger
|
98
|
-
end
|
99
|
-
|
100
101
|
trap(:INT) { poller.stop; exit }
|
101
102
|
|
102
103
|
begin
|