derfred-workling 0.4.9.1 → 0.4.9.2

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 (44) hide show
  1. data/lib/cattr_accessor.rb +51 -0
  2. data/lib/mattr_accessor.rb +55 -0
  3. data/lib/rude_q/client.rb +11 -0
  4. data/lib/workling/base.rb +115 -0
  5. data/lib/workling/clients/amqp_client.rb +38 -0
  6. data/lib/workling/clients/amqp_exchange_client.rb +50 -0
  7. data/lib/workling/clients/base.rb +57 -0
  8. data/lib/workling/clients/memcache_queue_client.rb +91 -0
  9. data/lib/workling/clients/sqs_client.rb +162 -0
  10. data/lib/workling/clients/xmpp_client.rb +100 -0
  11. data/lib/workling/discovery.rb +16 -0
  12. data/lib/workling/remote/invokers/amqp_single_subscriber.rb +45 -0
  13. data/lib/workling/remote/invokers/base.rb +124 -0
  14. data/lib/workling/remote/invokers/basic_poller.rb +41 -0
  15. data/lib/workling/remote/invokers/eventmachine_subscriber.rb +41 -0
  16. data/lib/workling/remote/invokers/looped_subscriber.rb +38 -0
  17. data/lib/workling/remote/invokers/thread_pool_poller.rb +169 -0
  18. data/lib/workling/remote/invokers/threaded_poller.rb +153 -0
  19. data/lib/workling/remote/runners/amqp_exchange_runner.rb +45 -0
  20. data/lib/workling/remote/runners/backgroundjob_runner.rb +35 -0
  21. data/lib/workling/remote/runners/base.rb +42 -0
  22. data/lib/workling/remote/runners/client_runner.rb +46 -0
  23. data/lib/workling/remote/runners/not_remote_runner.rb +23 -0
  24. data/lib/workling/remote/runners/not_runner.rb +17 -0
  25. data/lib/workling/remote/runners/rudeq_runner.rb +23 -0
  26. data/lib/workling/remote/runners/spawn_runner.rb +38 -0
  27. data/lib/workling/remote/runners/starling_runner.rb +13 -0
  28. data/lib/workling/remote.rb +69 -0
  29. data/lib/workling/return/store/base.rb +42 -0
  30. data/lib/workling/return/store/iterator.rb +24 -0
  31. data/lib/workling/return/store/memory_return_store.rb +26 -0
  32. data/lib/workling/return/store/rudeq_return_store.rb +24 -0
  33. data/lib/workling/return/store/starling_return_store.rb +31 -0
  34. data/lib/workling/routing/base.rb +16 -0
  35. data/lib/workling/routing/class_and_method_routing.rb +57 -0
  36. data/lib/workling/routing/static_routing.rb +47 -0
  37. data/lib/workling/rudeq/client.rb +17 -0
  38. data/lib/workling/rudeq/poller.rb +116 -0
  39. data/lib/workling/rudeq.rb +7 -0
  40. data/lib/workling.rb +195 -0
  41. data/lib/workling_server.rb +108 -0
  42. data/script/bj_invoker.rb +11 -0
  43. data/script/starling_status.rb +37 -0
  44. metadata +44 -1
@@ -0,0 +1,57 @@
1
+ require 'workling/routing/base'
2
+
3
+ #
4
+ # Holds a hash of routes. Each Worker method has a corresponding hash entry after building.
5
+ #
6
+ module Workling
7
+ module Routing
8
+ class ClassAndMethodRouting < Base
9
+
10
+ # initializes and builds routing hash.
11
+ def initialize(*args)
12
+ super
13
+
14
+ build
15
+ end
16
+
17
+ # returns the worker method name, given the routing string.
18
+ def method_name(queue)
19
+ self[queue].method_for(queue)
20
+ end
21
+
22
+ # returns the routing string, given a class and method. delegating.
23
+ def queue_for(clazz, method)
24
+ ClassAndMethodRouting.queue_for(clazz, method)
25
+ end
26
+
27
+ # returns the routing string, given a class and method.
28
+ def self.queue_for(clazz, method)
29
+ # this is lifted from the Rails constantize method
30
+ clazz = Object.module_eval("::#{clazz}") unless clazz.is_a?(Class)
31
+ clazz.queue_for method
32
+ end
33
+
34
+ # returns all routed
35
+ def queue_names
36
+ self.keys
37
+ end
38
+
39
+ # dare you to remove this! go on!
40
+ def queue_names_routing_class(clazz)
41
+ self.select { |x, y| y.is_a?(clazz) }.map { |x, y| x }
42
+ end
43
+
44
+ private
45
+ def build
46
+ Workling::Discovery.discovered.each do |clazz|
47
+ methods = clazz.public_instance_methods(false)
48
+ methods.each do |method|
49
+ next if method == 'create' # Skip the create method
50
+ queue = queue_for(clazz, method)
51
+ self[queue] = clazz.new
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,47 @@
1
+ require 'workling/routing/base'
2
+
3
+ #
4
+ # Holds a single route for a dedicated worker (if you want more worker processes, run more workers)
5
+ #
6
+ module Workling
7
+ module Routing
8
+ class StaticRouting < Base
9
+
10
+ #
11
+ # ./script/workling_client run -- <worker_class> <worker_method> <routing_key>
12
+ # ./script/workling_client run -- <worker_class> <worker_method> <routing_key> <queue_name>
13
+ #
14
+ def initialize(*args)
15
+ @worker = args[0].constantize.new
16
+ @method_name = args[1]
17
+ @routing_key = args[2]
18
+
19
+ if(args.size==4)
20
+ @queue_name = args[3]
21
+ else
22
+ @queue_name = [@worker.class.to_s.tableize, @method_name, @routing_key].join("__")
23
+ end
24
+
25
+ # so routing[x] hash access works as expected
26
+ self.default = @worker
27
+
28
+ puts "** static routing: queue - #{@queue_name}, routing_key - #{@routing_key}, method - #{@method_name}, worker - #{@worker.class}"
29
+ end
30
+
31
+ # returns the worker method name, given the routing string.
32
+ def method_name(queue=nil); @method_name; end
33
+
34
+ def routing_key_for; @routing_key; end
35
+
36
+ # returns the routing string, given a class and method. delegating.
37
+ # TODO - we can check for consistency here with clazz and methods vs. current configuration of this single route
38
+ def queue_for(clazz=nil, method=nil); @queue_name; end
39
+
40
+ # returns array containing the single configured route
41
+ def queue_names; [@queue_name]; end
42
+
43
+ # TODO - not sure what this is...
44
+ def queue_names_routing_class(clazz); @worker.class; end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,17 @@
1
+ require 'workling/rudeq'
2
+
3
+ module Workling
4
+ module Rudeq
5
+ class Client
6
+ attr_reader :queue
7
+
8
+ def initialize
9
+ @queue = Workling::Rudeq.config[:queue_class].constantize
10
+ end
11
+
12
+ def method_missing(method, *args)
13
+ @queue.send(method, *args)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,116 @@
1
+ require 'workling/rudeq'
2
+
3
+ module Workling
4
+ module Rudeq
5
+
6
+ class Poller
7
+
8
+ cattr_accessor :sleep_time # Seconds to sleep before looping
9
+ cattr_accessor :reset_time # Seconds to wait while resetting connection
10
+
11
+ def initialize(routing)
12
+ Poller.sleep_time = Workling::Rudeq.config[:sleep_time] || 2
13
+ Poller.reset_time = Workling::Rudeq.config[:reset_time] || 30
14
+
15
+ @routing = routing
16
+ @workers = ThreadGroup.new
17
+ end
18
+
19
+ def logger
20
+ Workling::Base.logger
21
+ end
22
+
23
+ def listen
24
+
25
+ # Allow concurrency for our tasks
26
+ ActiveRecord::Base.allow_concurrency = true
27
+
28
+ # Create a thread for each worker.
29
+ Workling::Discovery.discovered.each do |clazz|
30
+ logger.debug("Discovered listener #{clazz}")
31
+ @workers.add(Thread.new(clazz) { |c| clazz_listen(c) })
32
+ end
33
+
34
+ # Wait for all workers to complete
35
+ @workers.list.each { |t| t.join }
36
+
37
+ # Clean up all the connections.
38
+ ActiveRecord::Base.verify_active_connections!
39
+ end
40
+
41
+ # gracefully stop processing
42
+ def stop
43
+ @workers.list.each { |w| w[:shutdown] = true }
44
+ end
45
+
46
+ ##
47
+ ## Thread procs
48
+ ##
49
+
50
+ # Listen for one worker class
51
+ def clazz_listen(clazz)
52
+
53
+ logger.debug("Listener thread #{clazz.name} started")
54
+
55
+ # Read thread configuration if available
56
+ if Rudeq.config.has_key?(:listeners)
57
+ if Rudeq.config[:listeners].has_key?(clazz.to_s)
58
+ config = Rudeq.config[:listeners][clazz.to_s].symbolize_keys
59
+ thread_sleep_time = config[:sleep_time] if config.has_key?(:sleep_time)
60
+ end
61
+ end
62
+
63
+ hread_sleep_time ||= self.class.sleep_time
64
+
65
+ connection = Workling::Rudeq::Client.new
66
+ puts "** Starting Workling::Rudeq::Client for #{clazz.name} queue"
67
+
68
+ # Start dispatching those messages
69
+ while (!Thread.current[:shutdown]) do
70
+ begin
71
+
72
+ # Keep MySQL connection alive
73
+ unless ActiveRecord::Base.connection.active?
74
+ unless ActiveRecord::Base.connection.reconnect!
75
+ logger.fatal("FAILED - Database not available")
76
+ break
77
+ end
78
+ end
79
+
80
+ # Dispatch and process the messages
81
+ n = dispatch!(connection, clazz)
82
+ logger.debug("Listener thread #{clazz.name} processed #{n.to_s} queue items") if n > 0
83
+ sleep(self.class.sleep_time) unless n > 0
84
+ end
85
+ end
86
+
87
+ logger.debug("Listener thread #{clazz.name} ended")
88
+ end
89
+
90
+ # Dispatcher for one worker class.
91
+ # Returns the number of worker methods called
92
+ def dispatch!(connection, clazz)
93
+ n = 0
94
+ for queue in @routing.queue_names_routing_class(clazz)
95
+ begin
96
+ result = connection.get(queue)
97
+ if result
98
+ n += 1
99
+ handler = @routing[queue]
100
+ method_name = @routing.method_name(queue)
101
+ logger.debug("Calling #{handler.class.to_s}\##{method_name}(#{result.inspect})")
102
+ handler.send(method_name, result)
103
+ end
104
+ rescue
105
+ logger.error("FAILED to connect with queue #{ queue }: #{ e } }")
106
+ raise e
107
+ rescue Object => e
108
+ logger.error("FAILED to process queue #{ queue }. #{ @routing[queue] } could not handle invocation of #{ @routing.method_name(queue) } with #{ result.inspect }: #{ e }.\n#{ e.backtrace.join("\n") }")
109
+ end
110
+ end
111
+
112
+ return n
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,7 @@
1
+ module Workling
2
+ module Rudeq
3
+ def self.config
4
+ @@config ||= {:queue_class => "RudeQueue"}
5
+ end
6
+ end
7
+ end
data/lib/workling.rb ADDED
@@ -0,0 +1,195 @@
1
+ #
2
+ # I can haz am in your Workling are belong to us!
3
+ #
4
+ require 'mattr_accessor' unless Module.respond_to?(:mattr_accessor)
5
+ require 'cattr_accessor' unless Class.respond_to?(:cattr_accessor)
6
+
7
+ gem 'activesupport'
8
+ require 'active_support/inflector'
9
+ require 'active_support/core_ext/hash/keys'
10
+
11
+ class Hash #:nodoc:
12
+ include ActiveSupport::CoreExtensions::Hash::Keys
13
+ end
14
+
15
+ require 'yaml'
16
+
17
+ module Workling
18
+ class WorklingError < StandardError; end
19
+ class WorklingNotFoundError < WorklingError; end
20
+ class WorklingConnectionError < WorklingError; end
21
+ class QueueserverNotFoundError < WorklingError
22
+ def initialize
23
+ 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)"
24
+ end
25
+ end
26
+
27
+ class ConfigurationError < WorklingError
28
+ def initialize
29
+ super File.exist?(Workling.path('config', 'starling.yml')) ?
30
+ "config/starling.yml has been depracated. rename your config file to config/workling.yml then try again!" :
31
+ "config/workling.yml could not be loaded. check out README.markdown to see what this file should contain. "
32
+ end
33
+ end
34
+
35
+ def self.path(*args)
36
+ if defined?(RAILS_ROOT)
37
+ File.join(RAILS_ROOT, *args)
38
+ else
39
+ File.join(Dir.pwd, *args)
40
+ end
41
+ end
42
+
43
+ def self.env
44
+ @env ||= if defined?(RAILS_ENV)
45
+ RAILS_ENV.to_s
46
+ elsif defined?(RACK_ENV)
47
+ RACK_ENV.to_s
48
+ end
49
+ end
50
+
51
+ mattr_accessor :load_path
52
+ @@load_path = [ File.expand_path(path('app', 'workers')) ]
53
+
54
+ VERSION = "0.4.9"
55
+
56
+ #
57
+ # determine the runner to use if nothing is specifically set. workling will try to detect
58
+ # starling, spawn, or bj, in that order. if none of these are found, notremoterunner will
59
+ # be used.
60
+ #
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
+ 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
73
+ else
74
+ Workling::Remote::Runners::NotRemoteRunner.new
75
+ end
76
+ end
77
+
78
+ #
79
+ # gets the worker instance, given a class. the optional method argument will cause an
80
+ # exception to be raised if the worker instance does not respoind to said method.
81
+ #
82
+ def self.find(clazz, method = nil)
83
+ begin
84
+ inst = clazz.to_s.camelize.constantize.new
85
+ rescue NameError
86
+ raise_not_found(clazz, method)
87
+ end
88
+ raise_not_found(clazz, method) if method && !inst.respond_to?(method)
89
+ inst
90
+ end
91
+
92
+ # returns Workling::Return::Store.instance.
93
+ def self.return
94
+ Workling::Return::Store.instance
95
+ end
96
+
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
+ #
160
+ # returns a config hash. reads ./config/workling.yml
161
+ #
162
+ def self.config
163
+ return @@config if defined?(@@config) && @@config
164
+
165
+ config_path = File.join(RAILS_ROOT, 'config', 'workling.yml')
166
+ return nil unless File.exists?(config_path)
167
+
168
+ @@config ||= YAML.load_file(config_path)[RAILS_ENV || 'development'].symbolize_keys
169
+ @@config[:memcache_options].symbolize_keys! if @@config[:memcache_options]
170
+ @@config
171
+ end
172
+
173
+ #
174
+ # Raises exceptions thrown inside of the worker. normally, these are logged to
175
+ # logger.error. it's easy to miss these log calls while developing, though.
176
+ #
177
+ mattr_accessor :raise_exceptions
178
+ @@raise_exceptions = (RAILS_ENV == "test" || RAILS_ENV == "development")
179
+
180
+ def self.raise_exceptions?
181
+ @@raise_exceptions
182
+ end
183
+
184
+ private
185
+ def self.raise_not_found(clazz, method)
186
+ raise Workling::WorklingNotFoundError.new("could not find #{ clazz }:#{ method } workling. ")
187
+ end
188
+ end
189
+
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"
@@ -0,0 +1,108 @@
1
+ require 'optparse'
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
+
13
+
14
+ def self.partition_options(args)
15
+ daemon = []
16
+ workling = []
17
+ split_point = args.index("--") || args.size
18
+ daemon = args[0...split_point] if split_point > 0
19
+ workling = args[(split_point+1)..-1] if split_point and split_point < args.size
20
+ [daemon, workling]
21
+ end
22
+
23
+ def self.partition_daemons_options(args)
24
+ standard_options = %W{start stop restart run zap -t --ontop -f --force -h --help --version}
25
+ pass_through = args.select { |a| standard_options.include? a }
26
+ custom_options = args.reject { |a| standard_options.include? a }
27
+
28
+ [pass_through, custom_options]
29
+ end
30
+
31
+ def self.parse_daemon_options(argv)
32
+ options = {}
33
+ pass_through, args = partition_daemons_options argv
34
+ opts = OptionParser.new do |opts|
35
+ opts.banner = 'Usage: myapp [options]'
36
+ opts.separator ''
37
+ opts.on('-a', '--app-name APP_NAME', String,"specify the process name") { |v| options[:app_name] = v }
38
+ opts.on('-d', '--dir DIR', String, "the directory to run in") { |v| options[:dir] = v }
39
+ opts.on('-m', '--monitor',"specify the process name") { |v| options[:monitor] = true }
40
+ opts.on('-t', '--ontop') { |k, v| pass_through << v }
41
+ end
42
+ opts.parse!(partition_options(args).first)
43
+ options.merge(:ARGV => pass_through)
44
+ end
45
+
46
+ def self.parse_workling_options(args)
47
+ options = {}
48
+ opts = OptionParser.new do |opts|
49
+ opts.banner = 'Usage: myapp [options]'
50
+ 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 }
56
+ end
57
+ opts.parse!(partition_options(args).last)
58
+ options
59
+ end
60
+
61
+
62
+ def self.build_poller(options)
63
+ require 'workling/remote'
64
+ ["remote/invokers/*.rb", "routing/*.rb"].each do |pattern|
65
+ Dir.glob(pattern).each do |f|
66
+ require File.join(File.dirname(f), File.basename(f, ".rb"))
67
+ end
68
+ end
69
+
70
+ routing_class = Object.module_eval("::#{options[:routing_class]}")
71
+ client_class = Object.module_eval("::#{options[:client_class]}")
72
+ invoker_class = Object.module_eval("::#{options[:invoker_class]}")
73
+ invoker_class.new(routing_class.new, client_class)
74
+ end
75
+
76
+
77
+ 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'
84
+
85
+ Workling.load_path = options[:load_path]
86
+
87
+ Workling::Discovery.discover!
88
+ Workling.config
89
+
90
+ poller = build_poller options
91
+
92
+ puts '** Rails loaded.'
93
+ puts "** Starting #{ poller.class }..."
94
+ puts '** Use CTRL-C to stop.'
95
+
96
+ ActiveRecord::Base.logger = Workling::Base.logger
97
+ ActionController::Base.logger = Workling::Base.logger
98
+
99
+ trap(:INT) { poller.stop; exit }
100
+
101
+ begin
102
+ poller.listen
103
+ ensure
104
+ puts '** No Worklings found.' if Workling::Discovery.discovered.blank?
105
+ puts '** Exiting'
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,11 @@
1
+ @routing = Workling::Routing::ClassAndMethodRouting.new
2
+ unnormalized = REXML::Text::unnormalize(STDIN.read)
3
+ message, command, args = *unnormalized.match(/(^[^ ]*) (.*)/)
4
+ options = Hash.from_xml(args)["hash"]
5
+
6
+ if workling = @routing[command]
7
+ options = options.symbolize_keys
8
+ method_name = @routing.method_name(command)
9
+
10
+ workling.dispatch_to_worker_method(method_name, options)
11
+ end
@@ -0,0 +1,37 @@
1
+ require 'pp'
2
+
3
+ puts '=> Loading Rails...'
4
+
5
+ require File.dirname(__FILE__) + '/../config/environment'
6
+ require File.dirname(__FILE__) + '/../vendor/plugins/workling/lib/workling/remote/invokers/basic_poller'
7
+ require File.dirname(__FILE__) + '/../vendor/plugins/workling/lib/workling/routing/class_and_method_routing'
8
+
9
+ puts '** Rails loaded.'
10
+
11
+ trap(:INT) { exit }
12
+
13
+ client = Workling::Clients::MemcacheQueueClient.new
14
+
15
+ begin
16
+ client.connect
17
+ client.reset
18
+
19
+ client.stats # do this so that connection is shown as established below.
20
+
21
+ puts "Queue state:"
22
+ pp client.inspect
23
+ pp "Active?: #{client.active?}"
24
+ pp "Read Only?: #{client.readonly?}"
25
+ puts ""
26
+ puts "Servers:"
27
+ pp client.servers
28
+ puts ""
29
+ puts "Queue stats:"
30
+ pp client.stats
31
+
32
+ puts "\nThread Stats:"
33
+ pp Thread.list
34
+ ensure
35
+ puts '** Exiting'
36
+ client.close
37
+ 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.1
4
+ version: 0.4.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rany Keddo
@@ -26,6 +26,49 @@ 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
32
+ - lib/workling/base.rb
33
+ - lib/workling/clients/amqp_client.rb
34
+ - lib/workling/clients/amqp_exchange_client.rb
35
+ - lib/workling/clients/base.rb
36
+ - lib/workling/clients/memcache_queue_client.rb
37
+ - lib/workling/clients/sqs_client.rb
38
+ - lib/workling/clients/xmpp_client.rb
39
+ - 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
56
+ - lib/workling/remote.rb
57
+ - lib/workling/return/store/base.rb
58
+ - lib/workling/return/store/iterator.rb
59
+ - lib/workling/return/store/memory_return_store.rb
60
+ - lib/workling/return/store/rudeq_return_store.rb
61
+ - lib/workling/return/store/starling_return_store.rb
62
+ - lib/workling/routing/base.rb
63
+ - lib/workling/routing/class_and_method_routing.rb
64
+ - lib/workling/routing/static_routing.rb
65
+ - lib/workling/rudeq/client.rb
66
+ - lib/workling/rudeq/poller.rb
67
+ - lib/workling/rudeq.rb
68
+ - lib/workling.rb
69
+ - lib/workling_server.rb
70
+ - script/bj_invoker.rb
71
+ - script/starling_status.rb
29
72
  has_rdoc: true
30
73
  homepage: http://github.com/elecnix/workling
31
74
  post_install_message: