backgroundrb-rails3 1.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.
Files changed (126) hide show
  1. data/.autotest +17 -0
  2. data/ChangeLog +50 -0
  3. data/Gemfile +11 -0
  4. data/LICENSE +4 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README +22 -0
  7. data/Rakefile +128 -0
  8. data/TODO.org +5 -0
  9. data/app/controller/backgroundrb_status_controller.rb +6 -0
  10. data/backgroundrb-rails3.gemspec +219 -0
  11. data/config/backgroundrb.yml +11 -0
  12. data/doc/Rakefile +5 -0
  13. data/doc/config.yaml +2 -0
  14. data/doc/content/advanced/advanced.txt +76 -0
  15. data/doc/content/advanced/advanced.yaml +4 -0
  16. data/doc/content/bugs/bugs.txt +20 -0
  17. data/doc/content/bugs/bugs.yaml +5 -0
  18. data/doc/content/community/community.txt +36 -0
  19. data/doc/content/community/community.yaml +5 -0
  20. data/doc/content/content.txt +168 -0
  21. data/doc/content/content.yaml +5 -0
  22. data/doc/content/faq/faq.txt +41 -0
  23. data/doc/content/faq/faq.yaml +5 -0
  24. data/doc/content/rails/rails.txt +182 -0
  25. data/doc/content/rails/rails.yaml +5 -0
  26. data/doc/content/scheduling/scheduling.txt +166 -0
  27. data/doc/content/scheduling/scheduling.yaml +5 -0
  28. data/doc/content/workers/workers.txt +178 -0
  29. data/doc/content/workers/workers.yaml +5 -0
  30. data/doc/layouts/default/default.erb +56 -0
  31. data/doc/layouts/default/default.yaml +4 -0
  32. data/doc/lib/default.rb +7 -0
  33. data/doc/output/Assets/BG-Ad-Top.png +0 -0
  34. data/doc/output/Assets/BG-Body.png +0 -0
  35. data/doc/output/Assets/BG-Feed.png +0 -0
  36. data/doc/output/Assets/BG-Menu-Hover.png +0 -0
  37. data/doc/output/Assets/BG-Menu.png +0 -0
  38. data/doc/output/Assets/BG-Sidebar-Bottom.png +0 -0
  39. data/doc/output/Assets/Button-Feed.png +0 -0
  40. data/doc/output/images/bg-ad-top.png +0 -0
  41. data/doc/output/images/bg-body.png +0 -0
  42. data/doc/output/images/bg-feed.gif +0 -0
  43. data/doc/output/images/bg-footer.jpg +0 -0
  44. data/doc/output/images/bg-header.jpg +0 -0
  45. data/doc/output/images/bg-menu-hover.png +0 -0
  46. data/doc/output/images/bg-menu.png +0 -0
  47. data/doc/output/images/bg-sidebar-bottom.gif +0 -0
  48. data/doc/output/images/button-feed.png +0 -0
  49. data/doc/output/images/icon-comment.png +0 -0
  50. data/doc/output/images/more_icon.gif +0 -0
  51. data/doc/output/style.css +299 -0
  52. data/doc/page_defaults.yaml +13 -0
  53. data/doc/tasks/default.rake +3 -0
  54. data/doc/templates/default/default.txt +1 -0
  55. data/doc/templates/default/default.yaml +4 -0
  56. data/examples/backgroundrb.yml +25 -0
  57. data/examples/foo_controller.rb +48 -0
  58. data/examples/god_worker.rb +7 -0
  59. data/examples/worker_tests/god_worker_test.rb +8 -0
  60. data/examples/workers/error_worker.rb +17 -0
  61. data/examples/workers/foo_worker.rb +38 -0
  62. data/examples/workers/god_worker.rb +7 -0
  63. data/examples/workers/model_worker.rb +13 -0
  64. data/examples/workers/renewal_worker.rb +11 -0
  65. data/examples/workers/rss_worker.rb +26 -0
  66. data/examples/workers/server_worker.rb +31 -0
  67. data/examples/workers/world_worker.rb +12 -0
  68. data/examples/workers/xmpp_worker.rb +7 -0
  69. data/init.rb +7 -0
  70. data/install.rb +1 -0
  71. data/know_issues.org +5 -0
  72. data/lib/backgroundrb.rb +1 -0
  73. data/lib/backgroundrb/bdrb_client_helper.rb +8 -0
  74. data/lib/backgroundrb/bdrb_cluster_connection.rb +156 -0
  75. data/lib/backgroundrb/bdrb_config.rb +43 -0
  76. data/lib/backgroundrb/bdrb_conn_error.rb +29 -0
  77. data/lib/backgroundrb/bdrb_connection.rb +179 -0
  78. data/lib/backgroundrb/bdrb_job_queue.rb +79 -0
  79. data/lib/backgroundrb/bdrb_result.rb +19 -0
  80. data/lib/backgroundrb/bdrb_start_stop.rb +146 -0
  81. data/lib/backgroundrb/rails_worker_proxy.rb +181 -0
  82. data/lib/backgroundrb/railtie.rb +48 -0
  83. data/lib/generators/backgroundrb/bdrb_migration/USAGE +12 -0
  84. data/lib/generators/backgroundrb/bdrb_migration/bdrb_migration_generator.rb +15 -0
  85. data/lib/generators/backgroundrb/bdrb_migration/templates/migration.rb +27 -0
  86. data/lib/generators/backgroundrb/worker/USAGE +16 -0
  87. data/lib/generators/backgroundrb/worker/templates/unit_test.rb +12 -0
  88. data/lib/generators/backgroundrb/worker/templates/worker.rb +7 -0
  89. data/lib/generators/backgroundrb/worker/worker_generator.rb +14 -0
  90. data/lib/tasks/backgroundrb_tasks.rake +103 -0
  91. data/release_notes.org +48 -0
  92. data/release_points.org +46 -0
  93. data/script/backgroundrb +52 -0
  94. data/script/bdrb_test_helper.rb +99 -0
  95. data/script/load_worker_env.rb +31 -0
  96. data/script/monitrc +25 -0
  97. data/server/backgroundrb_server.rb +12 -0
  98. data/server/lib/bdrb_result_storage.rb +62 -0
  99. data/server/lib/bdrb_server_helper.rb +24 -0
  100. data/server/lib/bdrb_thread_pool.rb +127 -0
  101. data/server/lib/cron_trigger.rb +197 -0
  102. data/server/lib/invalid_dump_error.rb +4 -0
  103. data/server/lib/log_worker.rb +25 -0
  104. data/server/lib/master_proxy.rb +140 -0
  105. data/server/lib/master_worker.rb +187 -0
  106. data/server/lib/meta_worker.rb +432 -0
  107. data/server/lib/trigger.rb +34 -0
  108. data/test/bdrb_client_test_helper.rb +5 -0
  109. data/test/bdrb_test_helper.rb +35 -0
  110. data/test/client/backgroundrb.yml +17 -0
  111. data/test/client/test_bdrb_client_helper.rb +13 -0
  112. data/test/client/test_bdrb_cluster_connection.rb +162 -0
  113. data/test/client/test_bdrb_config.rb +20 -0
  114. data/test/client/test_bdrb_connection.rb +29 -0
  115. data/test/client/test_bdrb_job_queue.rb +63 -0
  116. data/test/client/test_worker_proxy.rb +130 -0
  117. data/test/server/test_cron_trigger.rb +281 -0
  118. data/test/server/test_master_proxy.rb +54 -0
  119. data/test/server/test_master_worker.rb +157 -0
  120. data/test/server/test_meta_worker.rb +281 -0
  121. data/test/server/test_result_storage.rb +14 -0
  122. data/test/socket_mocker.rb +34 -0
  123. data/test/workers/bar_worker.rb +10 -0
  124. data/test/workers/foo_worker.rb +10 -0
  125. data/uninstall.rb +1 -0
  126. metadata +345 -0
@@ -0,0 +1,34 @@
1
+ module BackgrounDRb
2
+ class Trigger
3
+
4
+ attr_accessor :start_time, :end_time, :repeat_interval
5
+
6
+ def initialize(opts={})
7
+ @start_time = Time.parse(opts[:start])
8
+ @end_time = Time.parse(opts[:end])
9
+ @repeat_interval = opts[:repeat_interval].to_i
10
+ end
11
+
12
+ def fire_after_time(time)
13
+ @start_time = time if not @start_time
14
+
15
+ # Support UNIX at-style scheduling, by just specifying a start
16
+ # time.
17
+ if @end_time.nil? and @repeat_interval.nil?
18
+ @end_time = start_time + 1
19
+ @repeat_interval = 1
20
+ end
21
+
22
+ case
23
+ when @end_time && time > @end_time
24
+ nil
25
+ when time < @start_time
26
+ @start_time
27
+ when @repeat_interval != nil && @repeat_interval > 0
28
+ time + @repeat_interval - ((time - @start_time) % @repeat_interval)
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,5 @@
1
+ require "rails_worker_proxy"
2
+ require "bdrb_connection"
3
+ require "bdrb_client_helper"
4
+ require "bdrb_cluster_connection"
5
+ require "bdrb_conn_error"
@@ -0,0 +1,35 @@
1
+ require "rubygems"
2
+ require "mocha"
3
+ require "test/spec"
4
+ require "active_record"
5
+ require "active_support"
6
+ require "yaml"
7
+ require "erb"
8
+
9
+ class BDRB_CONFIG
10
+ @config_value = {}
11
+ def self.fuck
12
+ @config_value
13
+ end
14
+ def self.set hash
15
+ @config_value = hash
16
+ end
17
+ def self.[] key
18
+ @config_value[key]
19
+ end
20
+ end
21
+
22
+ RAILS_HOME = File.expand_path(File.join(File.dirname(__FILE__) + "/../../../..")) unless defined?(RAILS_HOME)
23
+ PACKET_APP = RAILS_HOME + "/vendor/plugins/backgroundrb" unless defined?(PACKET_APP)
24
+ WORKER_ROOT = RAILS_HOME + "/vendor/plugins/backgroundrb/test/workers" unless defined?(WORKER_ROOT)
25
+ SERVER_LOGGER = RAILS_HOME + "/log/backgroundrb_debug.log" unless defined?(SERVER_LOGGER)
26
+
27
+ ["server","server/lib","lib","lib/backgroundrb"].each { |x| $LOAD_PATH.unshift(PACKET_APP + "/#{x}")}
28
+ $LOAD_PATH.unshift(WORKER_ROOT)
29
+
30
+ require "packet"
31
+ require "bdrb_config"
32
+
33
+ require "backgroundrb_server"
34
+
35
+
@@ -0,0 +1,17 @@
1
+ ---
2
+ :backgroundrb:
3
+ :ip: 0.0.0.0
4
+ :port: 11008
5
+ :log: foreground
6
+ :environment: development
7
+ :result_storage: memcache
8
+
9
+ :memcache: "localhost:11211"
10
+
11
+ # :client: "0.0.0.0:11006,0.0.0.0:11008"
12
+
13
+ :schedules:
14
+ :wow_worker:
15
+ :foo:
16
+ :trigger_args: */60 * * * * * *
17
+
@@ -0,0 +1,13 @@
1
+ require File.join(File.dirname(__FILE__) + "/../bdrb_test_helper")
2
+ require File.join(File.dirname(__FILE__) + "/../bdrb_client_test_helper")
3
+
4
+ context "For client helper" do
5
+ specify "should return correct worker key" do
6
+ class Foo
7
+ include BackgrounDRb::ClientHelper
8
+ end
9
+ a = Foo.new
10
+ a.gen_worker_key("hello","world").should == :hello_world
11
+ a.gen_worker_key("hello").should == :hello
12
+ end
13
+ end
@@ -0,0 +1,162 @@
1
+ require File.join(File.dirname(__FILE__) + "/../bdrb_test_helper")
2
+ require File.join(File.dirname(__FILE__) + "/../bdrb_client_test_helper")
3
+
4
+ context "For Cluster connection" do
5
+ class BackgrounDRb::Connection
6
+ attr_accessor :server_ip,:server_port,:cluster_conn,:connection_status
7
+ def establish_connection
8
+ @connection_status = true
9
+ end
10
+
11
+ def close_connection
12
+ @connection_status = false
13
+ end
14
+ def server_info; "#{@server_ip}:#{server_port}"; end
15
+ end
16
+
17
+ setup do
18
+ BDRB_CONFIG.set({:schedules=> {
19
+ :foo_worker => { :barbar=>{:trigger_args=>"*/5 * * * * * *"}}},
20
+ :backgroundrb=>{:port=>11008, :ip=>"0.0.0.0", :environment=> "production"},
21
+ :client => "localhost:11001,localhost:11002,localhost:11003"
22
+ })
23
+
24
+ @cluster_connection = BackgrounDRb::ClusterConnection.new
25
+ class << @cluster_connection
26
+ def ivar(var)
27
+ return instance_variable_get("@#{var}")
28
+ end
29
+ def iset(var,value)
30
+ instance_variable_set("@#{var}",value)
31
+ end
32
+ end
33
+ end
34
+
35
+ specify "should read config file and connect to specified servers" do
36
+ @cluster_connection.backend_connections.length.should == 4
37
+ @cluster_connection.bdrb_servers.length.should == 4
38
+ @cluster_connection.ivar(:round_robin).length.should == 4
39
+ @cluster_connection.backend_connections[0].server_info.should == "localhost:11001"
40
+ end
41
+
42
+ specify "should return worker chosen in round robin manner if nothing specified" do
43
+ t_conn = @cluster_connection.choose_server
44
+ t_conn.server_info.should == "localhost:11001"
45
+ t_conn = @cluster_connection.choose_server
46
+ t_conn.server_info.should == "localhost:11002"
47
+ end
48
+
49
+ specify "should return connection from chosen host if specified" do
50
+ t_conn = @cluster_connection.find_connection("localhost:11001")
51
+ t_conn.server_info.should == "localhost:11001"
52
+ end
53
+
54
+ specify "should return connection from local host if specified" do
55
+ t_conn = @cluster_connection.find_local
56
+ t_conn.server_info.should == "0.0.0.0:11008"
57
+ end
58
+
59
+ specify "should not return disconnected connections" do
60
+ t_conn = @cluster_connection.find_next_except_these(Array("localhost:11001"))
61
+ @cluster_connection.ivar(:disconnected_connections).size.should == 1
62
+ @cluster_connection.backend_connections.size.should == 3
63
+ server_infos = @cluster_connection.backend_connections.map(&:server_info)
64
+ server_infos.should.include "0.0.0.0:11008"
65
+ server_infos.should.include "localhost:11002"
66
+ server_infos.should.include "localhost:11003"
67
+ server_infos.should.not.include "localhost:11001"
68
+ t_conn.server_info.should.not == "localhost:11001"
69
+ end
70
+
71
+ specify "should discover new connections when time to discover" do
72
+ t_conn = @cluster_connection.find_next_except_these(Array("localhost:11001"))
73
+ @cluster_connection.ivar(:disconnected_connections).size.should == 1
74
+ @cluster_connection.backend_connections.size.should == 3
75
+ @cluster_connection.iset(:request_count,9)
76
+ worker_proxy = @cluster_connection.worker(:hello_worker)
77
+ @cluster_connection.ivar(:disconnected_connections).size.should == 0
78
+ @cluster_connection.backend_connections.size.should == 4
79
+ end
80
+
81
+ specify "discover service should run only when connections were dropped" do
82
+ @cluster_connection.iset(:request_count,9)
83
+ @cluster_connection.expects(:disover_periodically).never
84
+ worker_proxy = @cluster_connection.worker(:hello_worker)
85
+ end
86
+
87
+ specify "should work with new_worker method calls" do
88
+ @cluster_connection.backend_connections.each do |t_conn|
89
+ t_conn.expects(:new_worker).with(:worker => :hello_worker,:worker_key => "boy",:data => "boy").returns(true)
90
+ end
91
+ a = @cluster_connection.new_worker(:worker => :hello_worker,:worker_key => "boy",:data => "boy")
92
+ a.should == "boy"
93
+ end
94
+
95
+ specify "should work with all worker info methods" do
96
+ @cluster_connection.backend_connections.each do |t_conn|
97
+ t_conn.expects(:all_worker_info).returns(:status => :running)
98
+ end
99
+ foo = @cluster_connection.all_worker_info
100
+ foo.should == {"0.0.0.0:11008"=>{:status=>:running}, "localhost:11001"=>{:status=>:running}, "localhost:11002"=>{:status=>:running}, "localhost:11003"=>{:status=>:running}}
101
+ end
102
+ end
103
+
104
+ context "For single connections" do
105
+ class BackgrounDRb::Connection
106
+ attr_accessor :server_ip,:server_port,:cluster_conn,:connection_status
107
+ end
108
+
109
+ setup do
110
+ BDRB_CONFIG.set({:schedules=> {
111
+ :foo_worker => { :barbar=>{:trigger_args=>"*/5 * * * * * *"}}},
112
+ :backgroundrb=>{:port=>11008, :ip=>"0.0.0.0", :environment=> "production"}
113
+ })
114
+
115
+ @cluster_connection = BackgrounDRb::ClusterConnection.new
116
+ class << @cluster_connection
117
+ def ivar(var)
118
+ return instance_variable_get("@#{var}")
119
+ end
120
+ end
121
+ end
122
+
123
+ specify "should read config file and connect to servers" do
124
+ @cluster_connection.backend_connections.length.should == 1
125
+ @cluster_connection.bdrb_servers.length.should == 1
126
+ @cluster_connection.ivar(:round_robin).length.should == 1
127
+ @cluster_connection.backend_connections[0].server_info.should == "0.0.0.0:11008"
128
+ end
129
+ end
130
+
131
+ context "For memcache based result storage" do
132
+ setup do
133
+ options = { :schedules =>
134
+ {
135
+ :foo_worker => { :barbar=>{:trigger_args=>"*/5 * * * * * *"}}
136
+ },
137
+ :backgroundrb =>
138
+ {
139
+ :port=>11008, :ip=>"0.0.0.0", :environment=> "production",:result_storage => 'memcache'
140
+ },
141
+ :client => "localhost:11001,localhost:11002,localhost:11003",
142
+ :memcache => "10.0.0.1:11211,10.0.0.2:11211"
143
+ }
144
+ BDRB_CONFIG.set(options)
145
+
146
+ @cluster_connection = BackgrounDRb::ClusterConnection.new
147
+ class << @cluster_connection
148
+ def ivar(var)
149
+ return instance_variable_get("@#{var}")
150
+ end
151
+ def iset(var,value)
152
+ instance_variable_set("@#{var}",value)
153
+ end
154
+ end
155
+ end
156
+
157
+
158
+ specify "should use memcache based result storage if specified" do
159
+ @cluster_connection.cache.should.not == nil
160
+ @cluster_connection.cache.class.should == MemCache
161
+ end
162
+ end
@@ -0,0 +1,20 @@
1
+ require File.join(File.dirname(__FILE__) + "/../bdrb_test_helper")
2
+ require File.join(File.dirname(__FILE__) + "/../bdrb_client_test_helper")
3
+
4
+ context "For BackgrounDRb config" do
5
+ conf_file = File.join(File.dirname(__FILE__),"backgroundrb.yml")
6
+ specify "should setup correct environment from cmd options" do
7
+ BackgrounDRb::Config.parse_cmd_options(["-e", "production"])
8
+ BackgrounDRb::Config.read_config(conf_file)
9
+ ENV["RAILS_ENV"].should == "production"
10
+ RAILS_ENV.should == "production"
11
+ end
12
+
13
+ specify "should setup correct environment from conf file" do
14
+ ENV["RAILS_ENV"] = nil
15
+ BackgrounDRb::Config.parse_cmd_options([])
16
+ BackgrounDRb::Config.read_config(conf_file)
17
+ ENV["RAILS_ENV"].should == "development"
18
+ RAILS_ENV.should == "development"
19
+ end
20
+ end
@@ -0,0 +1,29 @@
1
+ require File.join(File.dirname(__FILE__) + "/../socket_mocker")
2
+ require File.join(File.dirname(__FILE__) + "/../bdrb_test_helper")
3
+ require File.join(File.dirname(__FILE__) + "/../bdrb_client_test_helper")
4
+
5
+ context "For Actual BackgrounDRB connection" do
6
+ setup do
7
+ options = {:schedules => {
8
+ :foo_worker => { :barbar=>{:trigger_args=>"*/5 * * * * * *"}}},
9
+ :backgroundrb=>{:port=>11008, :ip=>"0.0.0.0", :environment=> "production"},
10
+ :client => "localhost:11001,localhost:11002,localhost:11003"
11
+ }
12
+ BDRB_CONFIG.set(options)
13
+ @cluster = mock()
14
+ @foo_connection = BackgrounDRb::Connection.new('localhost',1267,"crap")
15
+ @foo_connection.stubs(:close_connection)
16
+ class << @foo_connection
17
+ attr_accessor :outgoing_data
18
+ def dump_object data
19
+ @outgoing_data = data
20
+ end
21
+ end
22
+ end
23
+
24
+ specify "should return nil if ask_result returns nil" do
25
+ a = @foo_connection.ask_result(:worker => 'foo_worker',:worker_key => 'bar',:job_key => 10)
26
+ a.should == nil
27
+ @foo_connection.outgoing_data.should == {:type=>:get_result, :job_key=>10, :worker=>"foo_worker", :worker_key=>"bar"}
28
+ end
29
+ end
@@ -0,0 +1,63 @@
1
+ require File.join(File.dirname(__FILE__) + "/../bdrb_test_helper")
2
+ require File.join(File.dirname(__FILE__) + "/../bdrb_client_test_helper")
3
+ require "bdrb_job_queue"
4
+
5
+ context "For BackgrounDRb job Queues" do
6
+ setup do
7
+ db_config_file = YAML.load(ERB.new(IO.read("#{RAILS_HOME}/config/database.yml")).result)
8
+ ActiveRecord::Base.establish_connection(db_config_file["test"])
9
+ BdrbJobQueue.destroy_all
10
+ end
11
+
12
+ specify "should insert job with proper params" do
13
+ BdrbJobQueue.insert_job(:worker_name => "hello_world",:worker_method => "foovar",:job_key => "cats",:args => "hello_world",:scheduled_at => Time.now.utc)
14
+ next_job = BdrbJobQueue.find_next("hello_world")
15
+ next_job.taken.should == 1
16
+ next_job.started_at.should.not.be nil
17
+ next_job.job_key.should == "cats"
18
+ next_job.worker_name.should == "hello_world"
19
+ next_job.worker_method.should == "foovar"
20
+ end
21
+
22
+ specify "should respect job priority" do
23
+
24
+ BdrbJobQueue.insert_job(:priority => 4, :worker_name => "hello_world",:worker_method => "foovar",:job_key => "4",:args => "priority 4", :scheduled_at => Time.now.utc)
25
+ BdrbJobQueue.insert_job(:priority => 1, :worker_name => "hello_world",:worker_method => "foovar",:job_key => "1",:args => "priority 1", :scheduled_at => Time.now.utc)
26
+ BdrbJobQueue.insert_job(:priority => 10, :worker_name => "hello_world",:worker_method => "foovar",:job_key => "10",:args => "priority 10", :scheduled_at => Time.now.utc)
27
+
28
+ [10,4,1].each do |priority|
29
+ next_job = BdrbJobQueue.find_next("hello_world")
30
+ next_job.taken.should == 1
31
+ next_job.started_at.should.not.be nil
32
+ next_job.job_key.should == priority.to_s
33
+ next_job.worker_name.should == "hello_world"
34
+ next_job.worker_method.should == "foovar"
35
+ next_job.priority.should == priority
36
+ end
37
+ end
38
+
39
+ specify "release_job should worker properly" do
40
+ BdrbJobQueue.insert_job(:worker_name => "hello_world",:worker_method => "foovar",:job_key => "cats",:args => "hello_world",:scheduled_at => Time.now.utc)
41
+ next_job = BdrbJobQueue.find_next("hello_world")
42
+ next_job.release_job
43
+ t = BdrbJobQueue.find_by_job_key("cats")
44
+ t.taken.should == 0
45
+ t.started_at.should == nil
46
+ end
47
+
48
+ specify "remove job should work properly" do
49
+ BdrbJobQueue.insert_job(:worker_name => "hello_world",:worker_method => "foovar",:job_key => "cats",:args => "hello_world",:scheduled_at => Time.now.utc)
50
+ BdrbJobQueue.remove_job(:worker_name => "hello_world",:worker_method => "foovar",:job_key => "cats")
51
+ t = BdrbJobQueue.find_by_job_key("cats")
52
+ t.should == nil
53
+ end
54
+
55
+ specify "finish should work properly" do
56
+ BdrbJobQueue.insert_job(:worker_name => "hello_world",:worker_method => "foovar",:job_key => "cats",:args => "hello_world",:scheduled_at => Time.now.utc)
57
+ t = BdrbJobQueue.find_next("hello_world")
58
+ t.finish!
59
+ t.finished.should == 1
60
+ t.finished_at.should.not == nil
61
+ t.job_key.should.match(/finished_\d+_cats/i)
62
+ end
63
+ end
@@ -0,0 +1,130 @@
1
+ require File.join(File.dirname(__FILE__) + "/../bdrb_test_helper")
2
+ require File.join(File.dirname(__FILE__) + "/../bdrb_client_test_helper")
3
+
4
+ context "Worker Proxy in general" do
5
+ setup do
6
+ BDRB_CONFIG.set({:schedules=> {
7
+ :foo_worker => { :barbar=>{:trigger_args=>"*/5 * * * * * *"}}},
8
+ :backgroundrb=>{:port=>11008, :ip=>"0.0.0.0", :environment=> "production"}
9
+ })
10
+
11
+ @cluster_conn = mock
12
+ @worker_proxy = BackgrounDRb::RailsWorkerProxy.new(:hello_worker,nil,@cluster_conn)
13
+ end
14
+
15
+ specify "should let you fetch results" do
16
+ @cluster_conn.expects(:backend_connections).returns([])
17
+ foo = @worker_proxy.ask_result(:foobar)
18
+ foo.should.be nil
19
+ end
20
+
21
+ specify "should let you invoke sync task methods" do
22
+ actual_conn = mock()
23
+ actual_conn.expects(:server_info).returns("localhost:11008")
24
+ actual_conn.expects(:send_request).returns({ :data => 20, :result_flag => "ok",:result => true, :type => :response})
25
+ @cluster_conn.expects(:choose_server).returns(actual_conn)
26
+ a = @worker_proxy.hello_world(:args => "sucks")
27
+ a.should == 20
28
+ end
29
+
30
+ specify "should let you invoke delete method" do
31
+ actual_conn = mock()
32
+ actual_conn.expects(:delete_worker).with(:worker => :hello_worker).returns(nil)
33
+ @cluster_conn.expects(:backend_connections).returns(Array(actual_conn))
34
+ @worker_proxy.delete
35
+ end
36
+
37
+ specify "delete method should run on all nodes" do
38
+ conn_array = (0..3).map do |i|
39
+ t = mock()
40
+ t.expects(:delete_worker).with(:worker => :hello_worker).returns(nil)
41
+ t
42
+ end
43
+ @cluster_conn.expects(:backend_connections).returns(conn_array)
44
+ @worker_proxy.delete
45
+ end
46
+
47
+ specify "should let you invoke worker_info method" do
48
+ backend_connections = []
49
+ 2.times { |i|
50
+ actual_conn = mock()
51
+ actual_conn.expects(:worker_info).with(:worker => :hello_worker).returns(i)
52
+ backend_connections << actual_conn
53
+ }
54
+ @cluster_conn.expects(:backend_connections).returns(backend_connections)
55
+ a = @worker_proxy.worker_info
56
+ a.should == [0,1]
57
+ end
58
+
59
+ specify "should let you run async tasks" do
60
+ actual_conn = mock()
61
+ actual_conn.expects(:ask_work).with(:arg => :hello,:worker => :hello_worker,:worker_method => 'foobar',:job_key => 'boy').returns(nil)
62
+ @cluster_conn.expects(:find_connection).returns(actual_conn)
63
+ @worker_proxy.async_foobar(:arg => :hello,:job_key => "boy",
64
+ :host => "192.168.2.100:100")
65
+ end
66
+
67
+ specify "for enqueued tasks" do
68
+ BdrbJobQueue = mock() unless Object.const_defined?(:BdrbJobQueue)
69
+ BdrbJobQueue.expects(:insert_job).with() { |value|
70
+ value[:worker_name].should == "hello_worker"
71
+ value[:worker_method].should == "foobar"
72
+ value[:scheduled_at].should.not == nil
73
+ value[:job_key] == "catz"
74
+ }
75
+ @worker_proxy.enq_foobar(:arg => :hello,:job_key => "catz")
76
+ end
77
+
78
+
79
+ specify "should run enqueued tasks in order if they have priorites" do
80
+
81
+ BdrbJobQueue = mock() unless Object.const_defined?(:BdrbJobQueue)
82
+
83
+ [2,4,10].each do |priority|
84
+ BdrbJobQueue.expects(:insert_job).with() { |value|
85
+ value[:worker_name].should == "hello_worker"
86
+ value[:worker_method].should == "foobar"
87
+ value[:scheduled_at].should.not == nil
88
+ value[:job_key] == priority.to_s
89
+ value[:priority] == priority
90
+ }.once
91
+ end
92
+
93
+ @worker_proxy.enq_foobar(:job_key => '4', :priority => 4, :arg => :hello)
94
+ @worker_proxy.enq_foobar(:job_key => '2', :priority => 2, :arg => :hello)
95
+ @worker_proxy.enq_foobar(:job_key => '10', :priority => 10, :arg => :hello)
96
+ end
97
+
98
+
99
+ specify "for removing tasks from the queue" do
100
+ BdrbJobQueue = mock() unless Object.const_defined?(:BdrbJobQueue)
101
+ BdrbJobQueue.expects(:remove_job).with() do |value|
102
+ value[:worker_name] == "hello_worker"
103
+ value[:worker_method] == "foobar"
104
+ value[:job_key] == "catz"
105
+ end
106
+ @worker_proxy.deq_foobar(:job_key => "catz")
107
+ end
108
+
109
+ specify "should run task on all servers if asked" do
110
+ backend_connections = []
111
+ 2.times { |i|
112
+ actual_conn = mock()
113
+ actual_conn.expects(:ask_work).with(:worker => :hello_worker,:worker_method => 'foobar',:job_key => 'hello')
114
+ backend_connections << actual_conn
115
+ }
116
+ @cluster_conn.expects(:backend_connections).returns(backend_connections)
117
+ a = @worker_proxy.async_foobar(:job_key => "hello",:host => :all)
118
+ end
119
+
120
+ specify "should switch connections if invoke fails on chosen one" do
121
+ end
122
+
123
+ specify "Should allow method with empty params to work" do
124
+ actual_conn = mock()
125
+ actual_conn.expects(:server_info).returns("localhost:11211")
126
+ actual_conn.expects(:ask_work).with(:worker => :hello_worker,:worker_method => 'foobar').returns(nil)
127
+ @cluster_conn.expects(:choose_server).returns(actual_conn)
128
+ @worker_proxy.async_foobar
129
+ end
130
+ end