qwirk 0.0.1
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/History.md +7 -0
- data/LICENSE.txt +201 -0
- data/README.md +180 -0
- data/Rakefile +34 -0
- data/examples/README +1 -0
- data/examples/activemq.xml +84 -0
- data/examples/advanced_requestor/README.md +15 -0
- data/examples/advanced_requestor/base_request_worker.rb +18 -0
- data/examples/advanced_requestor/char_count_worker.rb +16 -0
- data/examples/advanced_requestor/config.ru +24 -0
- data/examples/advanced_requestor/exception_raiser_worker.rb +17 -0
- data/examples/advanced_requestor/length_worker.rb +14 -0
- data/examples/advanced_requestor/print_worker.rb +14 -0
- data/examples/advanced_requestor/publisher.rb +49 -0
- data/examples/advanced_requestor/qwirk.yml +16 -0
- data/examples/advanced_requestor/reverse_worker.rb +14 -0
- data/examples/advanced_requestor/triple_worker.rb +14 -0
- data/examples/batch/my_batch_worker.rb +30 -0
- data/examples/batch/my_line_worker.rb +8 -0
- data/examples/qwirk.yml +20 -0
- data/examples/requestor/README.md +13 -0
- data/examples/requestor/config.ru +13 -0
- data/examples/requestor/qwirk_persist.yml +5 -0
- data/examples/requestor/requestor.rb +68 -0
- data/examples/requestor/reverse_echo_worker.rb +15 -0
- data/examples/setup.rb +13 -0
- data/examples/shared/README.md +24 -0
- data/examples/shared/config.ru +13 -0
- data/examples/shared/publisher.rb +49 -0
- data/examples/shared/qwirk_persist.yml +5 -0
- data/examples/shared/shared_worker.rb +16 -0
- data/examples/simple/README +53 -0
- data/examples/simple/bar_worker.rb +10 -0
- data/examples/simple/baz_worker.rb +10 -0
- data/examples/simple/config.ru +14 -0
- data/examples/simple/publisher.rb +49 -0
- data/examples/simple/qwirk_persist.yml +4 -0
- data/examples/simple/tmp/kahadb/db-1.log +0 -0
- data/examples/simple/tmp/kahadb/db.data +0 -0
- data/examples/simple/tmp/kahadb/db.redo +0 -0
- data/examples/task/README +47 -0
- data/examples/task/config.ru +14 -0
- data/examples/task/foo_worker.rb +10 -0
- data/examples/task/messages.out +1000 -0
- data/examples/task/publisher.rb +25 -0
- data/examples/task/qwirk_persist.yml +5 -0
- data/examples/task/task.rb +36 -0
- data/lib/qwirk.rb +63 -0
- data/lib/qwirk/adapter.rb +45 -0
- data/lib/qwirk/base_worker.rb +96 -0
- data/lib/qwirk/batch.rb +4 -0
- data/lib/qwirk/batch/acquire_file_strategy.rb +47 -0
- data/lib/qwirk/batch/active_record.rb +3 -0
- data/lib/qwirk/batch/active_record/batch_job.rb +111 -0
- data/lib/qwirk/batch/active_record/failed_record.rb +5 -0
- data/lib/qwirk/batch/active_record/outstanding_record.rb +6 -0
- data/lib/qwirk/batch/file_status_strategy.rb +86 -0
- data/lib/qwirk/batch/file_worker.rb +228 -0
- data/lib/qwirk/batch/job_status.rb +29 -0
- data/lib/qwirk/batch/parse_file_strategy.rb +48 -0
- data/lib/qwirk/engine.rb +9 -0
- data/lib/qwirk/loggable.rb +23 -0
- data/lib/qwirk/manager.rb +140 -0
- data/lib/qwirk/marshal_strategy.rb +74 -0
- data/lib/qwirk/marshal_strategy/bson.rb +37 -0
- data/lib/qwirk/marshal_strategy/json.rb +37 -0
- data/lib/qwirk/marshal_strategy/none.rb +26 -0
- data/lib/qwirk/marshal_strategy/ruby.rb +26 -0
- data/lib/qwirk/marshal_strategy/string.rb +25 -0
- data/lib/qwirk/marshal_strategy/yaml.rb +25 -0
- data/lib/qwirk/publish_handle.rb +170 -0
- data/lib/qwirk/publisher.rb +67 -0
- data/lib/qwirk/queue_adapter.rb +3 -0
- data/lib/qwirk/queue_adapter/active_mq.rb +13 -0
- data/lib/qwirk/queue_adapter/active_mq/publisher.rb +12 -0
- data/lib/qwirk/queue_adapter/active_mq/worker_config.rb +16 -0
- data/lib/qwirk/queue_adapter/in_mem.rb +7 -0
- data/lib/qwirk/queue_adapter/in_mem/factory.rb +45 -0
- data/lib/qwirk/queue_adapter/in_mem/publisher.rb +98 -0
- data/lib/qwirk/queue_adapter/in_mem/queue.rb +88 -0
- data/lib/qwirk/queue_adapter/in_mem/reply_queue.rb +56 -0
- data/lib/qwirk/queue_adapter/in_mem/topic.rb +48 -0
- data/lib/qwirk/queue_adapter/in_mem/worker.rb +63 -0
- data/lib/qwirk/queue_adapter/in_mem/worker_config.rb +59 -0
- data/lib/qwirk/queue_adapter/jms.rb +50 -0
- data/lib/qwirk/queue_adapter/jms/connection.rb +42 -0
- data/lib/qwirk/queue_adapter/jms/consumer.rb +37 -0
- data/lib/qwirk/queue_adapter/jms/publisher.rb +126 -0
- data/lib/qwirk/queue_adapter/jms/worker.rb +89 -0
- data/lib/qwirk/queue_adapter/jms/worker_config.rb +38 -0
- data/lib/qwirk/remote_exception.rb +42 -0
- data/lib/qwirk/request_worker.rb +62 -0
- data/lib/qwirk/task.rb +177 -0
- data/lib/qwirk/task.rb.sav +194 -0
- data/lib/qwirk/version.rb +3 -0
- data/lib/qwirk/worker.rb +222 -0
- data/lib/qwirk/worker_config.rb +187 -0
- data/lib/rails/generators/qwirk/qwirk_generator.rb +82 -0
- data/lib/rails/generators/qwirk/templates/initializer.rb +6 -0
- data/lib/rails/generators/qwirk/templates/migration.rb +9 -0
- data/lib/rails/generators/qwirk/templates/schema.rb +28 -0
- data/lib/rails/railties/tasks.rake +8 -0
- data/lib/tasks/qwirk_tasks.rake +4 -0
- data/test/base_test.rb +248 -0
- data/test/database.yml +14 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +45 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +22 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +26 -0
- data/test/dummy/config/environments/production.rb +49 -0
- data/test/dummy/config/environments/test.rb +35 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/log/development.log +0 -0
- data/test/dummy/log/production.log +0 -0
- data/test/dummy/log/server.log +0 -0
- data/test/dummy/log/test.log +0 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +26 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/javascripts/application.js +2 -0
- data/test/dummy/public/javascripts/controls.js +965 -0
- data/test/dummy/public/javascripts/dragdrop.js +974 -0
- data/test/dummy/public/javascripts/effects.js +1123 -0
- data/test/dummy/public/javascripts/prototype.js +6001 -0
- data/test/dummy/public/javascripts/rails.js +191 -0
- data/test/dummy/script/rails +6 -0
- data/test/integration/navigation_test.rb +7 -0
- data/test/jms.yml +9 -0
- data/test/jms_fail_test.rb +149 -0
- data/test/jms_requestor_block_test.rb +278 -0
- data/test/jms_requestor_test.rb +238 -0
- data/test/jms_test.rb +287 -0
- data/test/marshal_strategy_test.rb +62 -0
- data/test/support/integration_case.rb +5 -0
- data/test/test_helper.rb +7 -0
- data/test/test_helper.rbold +22 -0
- data/test/test_helper_active_record.rb +61 -0
- data/test/unit/qwirk/batch/acquire_file_strategy_test.rb +101 -0
- data/test/unit/qwirk/batch/active_record/batch_job_test.rb +35 -0
- data/test/unit/qwirk/batch/parse_file_strategy_test.rb +49 -0
- metadata +366 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Step 0
|
|
2
|
+
# Follow the directions for configuring jms.yml located in examples/README
|
|
3
|
+
|
|
4
|
+
# Step 1
|
|
5
|
+
# Start an ActiveMQ Server
|
|
6
|
+
|
|
7
|
+
# Step 2
|
|
8
|
+
# Start up the manager
|
|
9
|
+
rackup -p 4567
|
|
10
|
+
|
|
11
|
+
# Step 3
|
|
12
|
+
jruby publish.rb foobar 4 2
|
|
13
|
+
|
|
14
|
+
# Step 4
|
|
15
|
+
# Play around with the options in qwirk_persist.yml and repeat steps 2&3.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module BaseRequestWorker
|
|
2
|
+
include Qwirk::RequestWorker
|
|
3
|
+
|
|
4
|
+
config_accessor :sleep_time, :float, 'Number of seconds to sleep between messages', 0
|
|
5
|
+
|
|
6
|
+
def self.included(base)
|
|
7
|
+
Qwirk::Worker.included(base)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def perform(obj)
|
|
11
|
+
puts "#{self}: Received #{obj} at #{Time.now}"
|
|
12
|
+
if config.sleep_time > 0.0
|
|
13
|
+
puts "#{self}: Sleeping for #{config.sleep_time} at #{Time.now}"
|
|
14
|
+
sleep config.sleep_time
|
|
15
|
+
end
|
|
16
|
+
super
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class CharCountWorker
|
|
2
|
+
include Qwirk::RequestWorker
|
|
3
|
+
|
|
4
|
+
topic 'test_string', :response => {:marshal => :bson, :time_to_live => 5000}
|
|
5
|
+
config_accessor :sleep_time, :float, 'Number of seconds to sleep between messages', 0
|
|
6
|
+
|
|
7
|
+
def request(obj)
|
|
8
|
+
if config.sleep_time > 0.0
|
|
9
|
+
puts "#{self}: Sleeping for #{config.sleep_time} at #{Time.now}"
|
|
10
|
+
sleep config.sleep_time
|
|
11
|
+
end
|
|
12
|
+
hash = Hash.new(0)
|
|
13
|
+
obj.each_char {|c| hash[c] += 1}
|
|
14
|
+
hash
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require '../setup'
|
|
2
|
+
require './publisher'
|
|
3
|
+
require './char_count_worker'
|
|
4
|
+
require './exception_raiser_worker'
|
|
5
|
+
require './length_worker'
|
|
6
|
+
require './print_worker'
|
|
7
|
+
require './reverse_worker'
|
|
8
|
+
require './triple_worker'
|
|
9
|
+
|
|
10
|
+
# If we're not starting up a standalone publisher, then start up a manager
|
|
11
|
+
if ENV['RACK_ENV'] != 'publisher'
|
|
12
|
+
manager = Qwirk[$adapter_key].create_manager(:name => 'Worker', :persist_file => 'qwirk_persist.yml')
|
|
13
|
+
manager['CharCount'].max_count = 1
|
|
14
|
+
manager['ExceptionRaiser'].max_count = 1
|
|
15
|
+
manager['Length'].max_count = 1
|
|
16
|
+
manager['Print'].max_count = 1
|
|
17
|
+
manager['Reverse'].max_count = 1
|
|
18
|
+
manager['Triple'].max_count = 1
|
|
19
|
+
at_exit { manager.stop }
|
|
20
|
+
end
|
|
21
|
+
if ENV['RACK_ENV'] != 'worker'
|
|
22
|
+
Rumx::Bean.root.bean_add_child(:Publisher, Publisher.new($adapter_key))
|
|
23
|
+
end
|
|
24
|
+
run Rumx::Server
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class ExceptionRaiserWorker
|
|
2
|
+
include Qwirk::RequestWorker
|
|
3
|
+
|
|
4
|
+
topic 'test_string', :response => {:marshal => :string, :time_to_live => 5000}
|
|
5
|
+
|
|
6
|
+
config_accessor :raise_exception, :boolean, 'Raise an exception instead of handling the request', false
|
|
7
|
+
config_accessor :sleep_time, :float, 'Number of seconds to sleep between messages', 0
|
|
8
|
+
|
|
9
|
+
def request(obj)
|
|
10
|
+
if config.sleep_time > 0.0
|
|
11
|
+
puts "#{self}: Sleeping for #{config.sleep_time} at #{Time.now}"
|
|
12
|
+
sleep config.sleep_time
|
|
13
|
+
end
|
|
14
|
+
raise "Raising dummy exception on #{obj}" if config.raise_exception
|
|
15
|
+
"We decided not to raise on #{obj}"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class LengthWorker
|
|
2
|
+
include Qwirk::RequestWorker
|
|
3
|
+
|
|
4
|
+
topic 'test_string', :response => {:marshal => :ruby, :time_to_live => 5000}
|
|
5
|
+
config_accessor :sleep_time, :float, 'Number of seconds to sleep between messages', 0
|
|
6
|
+
|
|
7
|
+
def request(obj)
|
|
8
|
+
if config.sleep_time > 0.0
|
|
9
|
+
puts "#{self}: Sleeping for #{config.sleep_time} at #{Time.now}"
|
|
10
|
+
sleep config.sleep_time
|
|
11
|
+
end
|
|
12
|
+
obj.length
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class PrintWorker
|
|
2
|
+
include Qwirk::Worker
|
|
3
|
+
|
|
4
|
+
topic 'test_string'
|
|
5
|
+
config_accessor :sleep_time, :float, 'Number of seconds to sleep between messages', 0
|
|
6
|
+
|
|
7
|
+
def perform(obj)
|
|
8
|
+
if config.sleep_time > 0.0
|
|
9
|
+
puts "#{self}: Sleeping for #{config.sleep_time} at #{Time.now}"
|
|
10
|
+
sleep config.sleep_time
|
|
11
|
+
end
|
|
12
|
+
puts "#{self}: Received #{obj} at #{Time.now}"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'rumx'
|
|
2
|
+
require 'qwirk'
|
|
3
|
+
|
|
4
|
+
class Publisher
|
|
5
|
+
include Rumx::Bean
|
|
6
|
+
|
|
7
|
+
bean_attr_reader :messages, :hash, 'Message', :hash_type => :string, :allow_write => false
|
|
8
|
+
|
|
9
|
+
bean_operation :publish, :void, 'Publish and receive messages', [
|
|
10
|
+
[ :message, :string, 'Message to get sent', 'Hello' ],
|
|
11
|
+
[ :timeout, :float, 'Timeout on receiving response', 4.0 ],
|
|
12
|
+
[ :sleep_time, :float, "Time between publishing and receiving where we're supposedly working", 2.0 ]
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
def initialize(adapter_key)
|
|
16
|
+
@publisher = Qwirk[adapter_key].create_publisher(:topic_name => 'test_string', :response => true, :marshal => :string)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def publish(message, timeout, sleep_time)
|
|
20
|
+
@messages = {}
|
|
21
|
+
puts "Publishing at #{Time.now.to_f}"
|
|
22
|
+
handle = @publisher.publish(message)
|
|
23
|
+
sleep sleep_time
|
|
24
|
+
|
|
25
|
+
handle.read_response(timeout) do |response|
|
|
26
|
+
response.on_message 'CharCount' do |hash|
|
|
27
|
+
messages['CharCount'] = "returned #{hash.inspect} in #{response.msec_delta.to_i} ms"
|
|
28
|
+
end
|
|
29
|
+
response.on_message 'Length', 'Reverse', 'Triple' do |val|
|
|
30
|
+
messages[response.name] = "returned #{val} in #{response.msec_delta.to_i} ms"
|
|
31
|
+
end
|
|
32
|
+
response.on_message 'ExceptionRaiser' do |val|
|
|
33
|
+
messages[response.name] = "didn't raise an exception, returned \"#{val}\" in #{response.msec_delta.to_i} ms"
|
|
34
|
+
end
|
|
35
|
+
response.on_timeout 'Reverse' do
|
|
36
|
+
messages[response.name] = "Timed out with it's own timeout handler in #{response.msec_delta.to_i} ms"
|
|
37
|
+
end
|
|
38
|
+
response.on_timeout do
|
|
39
|
+
messages[response.name] = "timed out in #{response.msec_delta.to_i} ms"
|
|
40
|
+
end
|
|
41
|
+
response.on_remote_exception 'ExceptionRaiser' do |e|
|
|
42
|
+
messages[response.name] = "It figures that ExceptionRaiser would raise an exception: #{e.message} in #{response.msec_delta.to_i} ms"
|
|
43
|
+
end
|
|
44
|
+
response.on_remote_exception do |e|
|
|
45
|
+
messages[response.name] = "raised exception: #{e.message} in #{response.msec_delta.to_i} ms"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class ReverseWorker
|
|
2
|
+
include Qwirk::RequestWorker
|
|
3
|
+
|
|
4
|
+
topic 'test_string', :response => {:marshal => :string, :time_to_live => 5000}
|
|
5
|
+
config_accessor :sleep_time, :float, 'Number of seconds to sleep between messages', 0
|
|
6
|
+
|
|
7
|
+
def request(obj)
|
|
8
|
+
if config.sleep_time > 0.0
|
|
9
|
+
puts "#{self}: Sleeping for #{config.sleep_time} at #{Time.now}"
|
|
10
|
+
sleep config.sleep_time
|
|
11
|
+
end
|
|
12
|
+
obj.reverse
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class TripleWorker
|
|
2
|
+
include Qwirk::RequestWorker
|
|
3
|
+
|
|
4
|
+
topic 'test_string', :response => {:marshal => :string, :time_to_live => 5000}
|
|
5
|
+
config_accessor :sleep_time, :float, 'Number of seconds to sleep between messages', 0
|
|
6
|
+
|
|
7
|
+
def request(obj)
|
|
8
|
+
if config.sleep_time > 0.0
|
|
9
|
+
puts "#{self}: Sleeping for #{config.sleep_time} at #{Time.now}"
|
|
10
|
+
sleep config.sleep_time
|
|
11
|
+
end
|
|
12
|
+
obj * 3
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class MyBatchWorker
|
|
2
|
+
include Qwirk::Batch::FileWorker
|
|
3
|
+
|
|
4
|
+
file :glob => '/home/batch_files/**', :max_outstanding_requests => 100, :fail_threshold => 0.8, :save_period => 30.seconds
|
|
5
|
+
marshal :bson
|
|
6
|
+
|
|
7
|
+
def start_file(file, is_restart)
|
|
8
|
+
@outfile = File.open(output_file_for(file), 'a')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def record_to_object(line)
|
|
12
|
+
line_to_hash(line)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def process_response(hash)
|
|
16
|
+
@outfile.puts(hash_to_line(hash))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def failed
|
|
20
|
+
@outfile.close
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def stop
|
|
24
|
+
@outfile.close
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def finish_file
|
|
28
|
+
@outfile.close
|
|
29
|
+
end
|
|
30
|
+
end
|
data/examples/qwirk.yml
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
in_mem:
|
|
2
|
+
:adapter: InMem
|
|
3
|
+
:log_times: true
|
|
4
|
+
|
|
5
|
+
active_mq:
|
|
6
|
+
:adapter: ActiveMQ
|
|
7
|
+
:log_times: true
|
|
8
|
+
:factory: org.apache.activemq.ActiveMQConnectionFactory
|
|
9
|
+
:broker_url: tcp://localhost:61616
|
|
10
|
+
#:username: myuser
|
|
11
|
+
#:password: mypassword
|
|
12
|
+
|
|
13
|
+
active_mq_invm:
|
|
14
|
+
:adapter: ActiveMQ
|
|
15
|
+
:log_times: true
|
|
16
|
+
:factory: org.apache.activemq.ActiveMQConnectionFactory
|
|
17
|
+
:broker_url: vm://qwirk?brokerConfig=xbean:../activemq.xml
|
|
18
|
+
:object_message_serialization_defered: true
|
|
19
|
+
:username: qwirk
|
|
20
|
+
:password: qwirk
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Step 0
|
|
2
|
+
# Follow the directions for configuring jms.yml located in examples/README
|
|
3
|
+
|
|
4
|
+
# Step 1
|
|
5
|
+
# Start an ActiveMQ Server
|
|
6
|
+
|
|
7
|
+
# Step 2
|
|
8
|
+
# Start up the manager
|
|
9
|
+
rackup -p 4567
|
|
10
|
+
|
|
11
|
+
# Step 3
|
|
12
|
+
# Request 'my string' get reversed
|
|
13
|
+
jruby request.rb 'my string'
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require '../setup'
|
|
2
|
+
require './reverse_echo_worker'
|
|
3
|
+
require './requestor'
|
|
4
|
+
|
|
5
|
+
# If we're not starting up a standalone publisher, then start up a manager
|
|
6
|
+
if ENV['RACK_ENV'] != 'publisher'
|
|
7
|
+
manager = Qwirk[$adapter_key].create_manager(:name => 'Worker', :persist_file => 'qwirk_persist.yml')
|
|
8
|
+
at_exit { manager.stop }
|
|
9
|
+
end
|
|
10
|
+
if ENV['RACK_ENV'] != 'worker'
|
|
11
|
+
Rumx::Bean.root.bean_add_child(:Requestor, Requestor.new($adapter_key))
|
|
12
|
+
end
|
|
13
|
+
run Rumx::Server
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require 'rumx'
|
|
2
|
+
require 'qwirk'
|
|
3
|
+
|
|
4
|
+
class MessageInfo
|
|
5
|
+
include Rumx::Bean
|
|
6
|
+
|
|
7
|
+
bean_attr_reader :request, :string, 'The message that was sent'
|
|
8
|
+
bean_attr_reader :response, :string, 'The response that was received'
|
|
9
|
+
|
|
10
|
+
def initialize(request, response)
|
|
11
|
+
@request, @response = request, response
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class Requestor
|
|
16
|
+
include Rumx::Bean
|
|
17
|
+
|
|
18
|
+
bean_reader :messages, :list, 'Messages', :list_type => :bean
|
|
19
|
+
|
|
20
|
+
bean_operation :publish, :void, 'Publish and receive messages', [
|
|
21
|
+
[ :message, :string, 'Message to get sent', 'Hello' ],
|
|
22
|
+
[ :timeout, :float, 'Timeout on receiving response', 4.0 ],
|
|
23
|
+
[ :sleep_time, :float, "Time between publishing and receiving where we're supposedly working", 2.0 ],
|
|
24
|
+
[ :thread_count, :integer, 'Number of different threads that are publishing and receiving the message', 10 ]
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def initialize(adapter_key)
|
|
29
|
+
@outstanding_hash_mutex = Mutex.new
|
|
30
|
+
@messages = []
|
|
31
|
+
@publisher = Qwirk[adapter_key].create_publisher(:queue_name => 'ReverseEcho', :response => {:time_to_live => 10000}, :marshal => :string)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def publish(message, timeout, sleep_time, thread_count)
|
|
35
|
+
@outstanding_hash_mutex.synchronize do
|
|
36
|
+
@messages = []
|
|
37
|
+
end
|
|
38
|
+
threads = []
|
|
39
|
+
(0...thread_count).each do |i|
|
|
40
|
+
threads << Thread.new(i) do |i|
|
|
41
|
+
puts "#{i}: Publishing at #{Time.now.to_f}"
|
|
42
|
+
request = "##{i}: #{message}"
|
|
43
|
+
response = nil
|
|
44
|
+
begin
|
|
45
|
+
handle = @publisher.publish(request)
|
|
46
|
+
# Here's where we'd go off and do other work
|
|
47
|
+
sleep sleep_time
|
|
48
|
+
puts "#{i}: Finished sleeping at #{Time.now.to_f}"
|
|
49
|
+
response = handle.read_response(timeout)
|
|
50
|
+
puts "#{i}: Received at #{Time.now.to_f}: #{response}"
|
|
51
|
+
rescue Exception => e
|
|
52
|
+
puts "#{i}: Exception: #{e.message}\n\t#{e.backtrace.join("\n\t")}"
|
|
53
|
+
response = e.message
|
|
54
|
+
end
|
|
55
|
+
@outstanding_hash_mutex.synchronize do
|
|
56
|
+
@messages << MessageInfo.new(request, response)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
threads.each {|t| t.join}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def messages
|
|
64
|
+
@outstanding_hash_mutex.synchronize do
|
|
65
|
+
return @messages.dup
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class ReverseEchoWorker
|
|
2
|
+
include Qwirk::RequestWorker
|
|
3
|
+
|
|
4
|
+
def request(obj)
|
|
5
|
+
puts "#{self}: Received #{obj} at #{Time.now}"
|
|
6
|
+
if obj =~ /^sleep (.*)/
|
|
7
|
+
sleep $1.to_f
|
|
8
|
+
puts "#{self}: Finished sleeping at #{Time.now}"
|
|
9
|
+
end
|
|
10
|
+
if obj =~ /^Exception/
|
|
11
|
+
raise Exception, 'You requested an exception'
|
|
12
|
+
end
|
|
13
|
+
obj.reverse
|
|
14
|
+
end
|
|
15
|
+
end
|
data/examples/setup.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Allow examples to be run in-place without requiring a gem install
|
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
|
3
|
+
|
|
4
|
+
require 'rubygems'
|
|
5
|
+
require 'qwirk'
|
|
6
|
+
require 'rumx'
|
|
7
|
+
require 'yaml'
|
|
8
|
+
require 'logger'
|
|
9
|
+
|
|
10
|
+
#Qwirk.logger = Logger.new($stdout)
|
|
11
|
+
file = File.expand_path('../qwirk.yml', __FILE__)
|
|
12
|
+
Qwirk.config = YAML.load(ERB.new(File.read(file), nil, '-').result(binding))
|
|
13
|
+
$adapter_key = ENV['QWIRK_ADAPTER'] || 'in_mem'
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
## Step 0
|
|
2
|
+
### Follow the directions for configuring configuring a JMS or InMem adapter located in examples/README
|
|
3
|
+
|
|
4
|
+
## Step 1
|
|
5
|
+
### Start up the application
|
|
6
|
+
* rm -f qwirk_persist.yml
|
|
7
|
+
* rackup -p 4567
|
|
8
|
+
|
|
9
|
+
## Step 2
|
|
10
|
+
* Browse to http://localhost:4567
|
|
11
|
+
* Open up the tree to Qwirk => S1 => Attributes
|
|
12
|
+
* Enter 2 for count and click the Update button.
|
|
13
|
+
* Open up the tree to Qwirk => S2 => Attributes
|
|
14
|
+
* Enter 3 for count and click the Update button.
|
|
15
|
+
* Refresh the browser so that you get the worker updates to the tree
|
|
16
|
+
|
|
17
|
+
## Step 3
|
|
18
|
+
* Open the tree to Publisher => Operations => send\_bar or send\_baz
|
|
19
|
+
* Enter values for the various arguments and click Execute.
|
|
20
|
+
|
|
21
|
+
## Step 4
|
|
22
|
+
* cntl-c the rackup process and start it back up. It should come back with
|
|
23
|
+
the workers and the config values that have been configured via the browser.
|
|
24
|
+
|