derfred-workling 0.4.9.5 → 0.4.9.6
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.
- 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
|