backgroundrb-rails3 1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +17 -0
- data/ChangeLog +50 -0
- data/Gemfile +11 -0
- data/LICENSE +4 -0
- data/MIT-LICENSE +20 -0
- data/README +22 -0
- data/Rakefile +128 -0
- data/TODO.org +5 -0
- data/app/controller/backgroundrb_status_controller.rb +6 -0
- data/backgroundrb-rails3.gemspec +219 -0
- data/config/backgroundrb.yml +11 -0
- data/doc/Rakefile +5 -0
- data/doc/config.yaml +2 -0
- data/doc/content/advanced/advanced.txt +76 -0
- data/doc/content/advanced/advanced.yaml +4 -0
- data/doc/content/bugs/bugs.txt +20 -0
- data/doc/content/bugs/bugs.yaml +5 -0
- data/doc/content/community/community.txt +36 -0
- data/doc/content/community/community.yaml +5 -0
- data/doc/content/content.txt +168 -0
- data/doc/content/content.yaml +5 -0
- data/doc/content/faq/faq.txt +41 -0
- data/doc/content/faq/faq.yaml +5 -0
- data/doc/content/rails/rails.txt +182 -0
- data/doc/content/rails/rails.yaml +5 -0
- data/doc/content/scheduling/scheduling.txt +166 -0
- data/doc/content/scheduling/scheduling.yaml +5 -0
- data/doc/content/workers/workers.txt +178 -0
- data/doc/content/workers/workers.yaml +5 -0
- data/doc/layouts/default/default.erb +56 -0
- data/doc/layouts/default/default.yaml +4 -0
- data/doc/lib/default.rb +7 -0
- data/doc/output/Assets/BG-Ad-Top.png +0 -0
- data/doc/output/Assets/BG-Body.png +0 -0
- data/doc/output/Assets/BG-Feed.png +0 -0
- data/doc/output/Assets/BG-Menu-Hover.png +0 -0
- data/doc/output/Assets/BG-Menu.png +0 -0
- data/doc/output/Assets/BG-Sidebar-Bottom.png +0 -0
- data/doc/output/Assets/Button-Feed.png +0 -0
- data/doc/output/images/bg-ad-top.png +0 -0
- data/doc/output/images/bg-body.png +0 -0
- data/doc/output/images/bg-feed.gif +0 -0
- data/doc/output/images/bg-footer.jpg +0 -0
- data/doc/output/images/bg-header.jpg +0 -0
- data/doc/output/images/bg-menu-hover.png +0 -0
- data/doc/output/images/bg-menu.png +0 -0
- data/doc/output/images/bg-sidebar-bottom.gif +0 -0
- data/doc/output/images/button-feed.png +0 -0
- data/doc/output/images/icon-comment.png +0 -0
- data/doc/output/images/more_icon.gif +0 -0
- data/doc/output/style.css +299 -0
- data/doc/page_defaults.yaml +13 -0
- data/doc/tasks/default.rake +3 -0
- data/doc/templates/default/default.txt +1 -0
- data/doc/templates/default/default.yaml +4 -0
- data/examples/backgroundrb.yml +25 -0
- data/examples/foo_controller.rb +48 -0
- data/examples/god_worker.rb +7 -0
- data/examples/worker_tests/god_worker_test.rb +8 -0
- data/examples/workers/error_worker.rb +17 -0
- data/examples/workers/foo_worker.rb +38 -0
- data/examples/workers/god_worker.rb +7 -0
- data/examples/workers/model_worker.rb +13 -0
- data/examples/workers/renewal_worker.rb +11 -0
- data/examples/workers/rss_worker.rb +26 -0
- data/examples/workers/server_worker.rb +31 -0
- data/examples/workers/world_worker.rb +12 -0
- data/examples/workers/xmpp_worker.rb +7 -0
- data/init.rb +7 -0
- data/install.rb +1 -0
- data/know_issues.org +5 -0
- data/lib/backgroundrb.rb +1 -0
- data/lib/backgroundrb/bdrb_client_helper.rb +8 -0
- data/lib/backgroundrb/bdrb_cluster_connection.rb +156 -0
- data/lib/backgroundrb/bdrb_config.rb +43 -0
- data/lib/backgroundrb/bdrb_conn_error.rb +29 -0
- data/lib/backgroundrb/bdrb_connection.rb +179 -0
- data/lib/backgroundrb/bdrb_job_queue.rb +79 -0
- data/lib/backgroundrb/bdrb_result.rb +19 -0
- data/lib/backgroundrb/bdrb_start_stop.rb +146 -0
- data/lib/backgroundrb/rails_worker_proxy.rb +181 -0
- data/lib/backgroundrb/railtie.rb +48 -0
- data/lib/generators/backgroundrb/bdrb_migration/USAGE +12 -0
- data/lib/generators/backgroundrb/bdrb_migration/bdrb_migration_generator.rb +15 -0
- data/lib/generators/backgroundrb/bdrb_migration/templates/migration.rb +27 -0
- data/lib/generators/backgroundrb/worker/USAGE +16 -0
- data/lib/generators/backgroundrb/worker/templates/unit_test.rb +12 -0
- data/lib/generators/backgroundrb/worker/templates/worker.rb +7 -0
- data/lib/generators/backgroundrb/worker/worker_generator.rb +14 -0
- data/lib/tasks/backgroundrb_tasks.rake +103 -0
- data/release_notes.org +48 -0
- data/release_points.org +46 -0
- data/script/backgroundrb +52 -0
- data/script/bdrb_test_helper.rb +99 -0
- data/script/load_worker_env.rb +31 -0
- data/script/monitrc +25 -0
- data/server/backgroundrb_server.rb +12 -0
- data/server/lib/bdrb_result_storage.rb +62 -0
- data/server/lib/bdrb_server_helper.rb +24 -0
- data/server/lib/bdrb_thread_pool.rb +127 -0
- data/server/lib/cron_trigger.rb +197 -0
- data/server/lib/invalid_dump_error.rb +4 -0
- data/server/lib/log_worker.rb +25 -0
- data/server/lib/master_proxy.rb +140 -0
- data/server/lib/master_worker.rb +187 -0
- data/server/lib/meta_worker.rb +432 -0
- data/server/lib/trigger.rb +34 -0
- data/test/bdrb_client_test_helper.rb +5 -0
- data/test/bdrb_test_helper.rb +35 -0
- data/test/client/backgroundrb.yml +17 -0
- data/test/client/test_bdrb_client_helper.rb +13 -0
- data/test/client/test_bdrb_cluster_connection.rb +162 -0
- data/test/client/test_bdrb_config.rb +20 -0
- data/test/client/test_bdrb_connection.rb +29 -0
- data/test/client/test_bdrb_job_queue.rb +63 -0
- data/test/client/test_worker_proxy.rb +130 -0
- data/test/server/test_cron_trigger.rb +281 -0
- data/test/server/test_master_proxy.rb +54 -0
- data/test/server/test_master_worker.rb +157 -0
- data/test/server/test_meta_worker.rb +281 -0
- data/test/server/test_result_storage.rb +14 -0
- data/test/socket_mocker.rb +34 -0
- data/test/workers/bar_worker.rb +10 -0
- data/test/workers/foo_worker.rb +10 -0
- data/uninstall.rb +1 -0
- metadata +345 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
# Model for storing jobs/tasks persisted to the database
|
2
|
+
|
3
|
+
class BdrbJobQueue < ActiveRecord::Base
|
4
|
+
validates_uniqueness_of :job_key,:scope => [:worker_name,:worker_key]
|
5
|
+
# find next task from the table
|
6
|
+
def self.find_next(worker_name,worker_key = nil)
|
7
|
+
returned_job = nil
|
8
|
+
ActiveRecord::Base.verify_active_connections!
|
9
|
+
transaction do
|
10
|
+
unless worker_key
|
11
|
+
#use ruby time stamps for time calculations as db might have different times than what is calculated by ruby/rails
|
12
|
+
t_job = find(:first,:conditions => [" worker_name = ? AND taken = ? AND scheduled_at <= ? ", worker_name, 0, Time.now.utc ],:lock => true, :order => 'priority desc')
|
13
|
+
else
|
14
|
+
t_job = find(:first,:conditions => [" worker_name = ? AND taken = ? AND worker_key = ? AND scheduled_at <= ? ", worker_name, 0, worker_key, Time.now.utc ],:lock => true)
|
15
|
+
end
|
16
|
+
if t_job
|
17
|
+
t_job.taken = 1
|
18
|
+
t_job.started_at = Time.now.utc
|
19
|
+
t_job.save
|
20
|
+
returned_job = t_job
|
21
|
+
end
|
22
|
+
end
|
23
|
+
returned_job
|
24
|
+
end
|
25
|
+
|
26
|
+
#these accessors get around any possible character encoding issues with the database
|
27
|
+
def args=(args)
|
28
|
+
write_attribute(:args, Base64.encode64(args))
|
29
|
+
end
|
30
|
+
|
31
|
+
def args
|
32
|
+
Base64.decode64(read_attribute(:args))
|
33
|
+
end
|
34
|
+
|
35
|
+
# release a job and mark it to be unfinished and free.
|
36
|
+
# useful, if inside a worker, processing of this job failed and you want it to process later
|
37
|
+
def release_job
|
38
|
+
ActiveRecord::Base.verify_active_connections!
|
39
|
+
self.class.transaction do
|
40
|
+
self.taken = 0
|
41
|
+
self.started_at = nil
|
42
|
+
self.save
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# insert a new job for processing. jobs added will be automatically picked by the appropriate worker
|
47
|
+
def self.insert_job(options = { })
|
48
|
+
ActiveRecord::Base.verify_active_connections!
|
49
|
+
transaction do
|
50
|
+
options.merge!(:submitted_at => Time.now.utc,:finished => 0,:taken => 0)
|
51
|
+
t_job = new(options)
|
52
|
+
t_job.save
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# remove a job from table
|
57
|
+
def self.remove_job(options = { })
|
58
|
+
ActiveRecord::Base.verify_active_connections!
|
59
|
+
transaction do
|
60
|
+
t_job_id = find(:first, :conditions => options.merge(:finished => 0,:taken => 0),:lock => true)
|
61
|
+
delete(t_job_id)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Mark a job as finished
|
66
|
+
def finish!
|
67
|
+
ActiveRecord::Base.verify_active_connections!
|
68
|
+
self.class.transaction do
|
69
|
+
self.finished = 1
|
70
|
+
self.finished_at = Time.now.utc
|
71
|
+
self.job_key = "finished_#{Time.now.utc.to_i}_#{job_key}"
|
72
|
+
self.save
|
73
|
+
end
|
74
|
+
Thread.current[:persistent_job_id] = nil
|
75
|
+
Thread.current[:job_key] = nil
|
76
|
+
nil
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module BackgrounDRb
|
2
|
+
class Result
|
3
|
+
def initialize results
|
4
|
+
@results = resuls
|
5
|
+
end
|
6
|
+
|
7
|
+
def async_response?
|
8
|
+
!(@results[:result] == true)
|
9
|
+
end
|
10
|
+
|
11
|
+
def sync_response?
|
12
|
+
(@results[:result] == true)
|
13
|
+
end
|
14
|
+
|
15
|
+
def error?
|
16
|
+
!(@results[:result_flag] == "ok")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# see http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
|
2
|
+
# for LSB-compliancy info
|
3
|
+
module BackgrounDRb
|
4
|
+
class StartStop
|
5
|
+
def start
|
6
|
+
if running? # starting an already running process is considered a success
|
7
|
+
puts "BackgrounDRb Already Running"
|
8
|
+
exit(0)
|
9
|
+
elsif dead? # dead, but pid exists
|
10
|
+
remove_pidfiles
|
11
|
+
end
|
12
|
+
|
13
|
+
# status == 3, not running.
|
14
|
+
STDOUT.sync = true
|
15
|
+
print("Starting BackgrounDRb .... ")
|
16
|
+
start_bdrb
|
17
|
+
puts "Success!"
|
18
|
+
end
|
19
|
+
|
20
|
+
def stop
|
21
|
+
pid_files = Dir["#{RAILS_HOME}/tmp/pids/backgroundrb_*.pid"]
|
22
|
+
puts "BackgrounDRb Not Running" if pid_files.empty?
|
23
|
+
pid_files.each do |x|
|
24
|
+
begin
|
25
|
+
kill_process(x)
|
26
|
+
rescue Errno::ESRCH
|
27
|
+
# stopping an already stopped process is considered a success (exit status 0)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
remove_pidfiles
|
31
|
+
end
|
32
|
+
|
33
|
+
# returns the correct lsb code for the status:
|
34
|
+
# 0 program is running or service is OK
|
35
|
+
# 1 program is dead and /var/run pid file exists
|
36
|
+
# 3 program is not running
|
37
|
+
def status
|
38
|
+
@status ||= begin
|
39
|
+
if pidfile_exists? and process_running?
|
40
|
+
0
|
41
|
+
elsif pidfile_exists? # but not process_running
|
42
|
+
1
|
43
|
+
else
|
44
|
+
3
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
return @status
|
49
|
+
end
|
50
|
+
|
51
|
+
def pidfile_exists?; File.exists?(PID_FILE); end
|
52
|
+
|
53
|
+
def process_running?
|
54
|
+
begin
|
55
|
+
Process.kill(0,self.pid)
|
56
|
+
true
|
57
|
+
rescue Errno::ESRCH
|
58
|
+
false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def running?;status == 0;end
|
63
|
+
# pidfile exists but process isn't running
|
64
|
+
|
65
|
+
def dead?;status == 1;end
|
66
|
+
|
67
|
+
def pid
|
68
|
+
File.read(PID_FILE).strip.to_i if pidfile_exists?
|
69
|
+
end
|
70
|
+
|
71
|
+
def remove_pidfiles
|
72
|
+
require 'fileutils'
|
73
|
+
FileUtils.rm_r(Dir["#{RAILS_HOME}/tmp/pids/backgroundrb_*.pid"])
|
74
|
+
end
|
75
|
+
|
76
|
+
def start_bdrb
|
77
|
+
require "rubygems"
|
78
|
+
require "yaml"
|
79
|
+
require "erb"
|
80
|
+
require "logger"
|
81
|
+
require "packet"
|
82
|
+
require "optparse"
|
83
|
+
|
84
|
+
require "bdrb_config"
|
85
|
+
require RAILS_HOME + "/config/boot"
|
86
|
+
require "active_support"
|
87
|
+
|
88
|
+
BackgrounDRb::Config.parse_cmd_options ARGV
|
89
|
+
|
90
|
+
require RAILS_HOME + "/config/environment"
|
91
|
+
require "bdrb_job_queue"
|
92
|
+
require "backgroundrb_server"
|
93
|
+
|
94
|
+
#proper way to daemonize - double fork to ensure parent can have no interest in the grandchild
|
95
|
+
if fork # Parent exits, child continues.
|
96
|
+
sleep(5)
|
97
|
+
exit(0)
|
98
|
+
else
|
99
|
+
Process.setsid # Become session leader.
|
100
|
+
|
101
|
+
op = File.open(PID_FILE, "w")
|
102
|
+
op.write(Process.pid().to_s)
|
103
|
+
op.close
|
104
|
+
|
105
|
+
if BDRB_CONFIG[:backgroundrb][:log].nil? or BDRB_CONFIG[:backgroundrb][:log] != 'foreground'
|
106
|
+
redirect_io(SERVER_LOGGER)
|
107
|
+
end
|
108
|
+
$0 = "backgroundrb master"
|
109
|
+
BackgrounDRb::MasterProxy.new()
|
110
|
+
end
|
111
|
+
|
112
|
+
#File.open(PID_FILE, "w") {|pidfile| pidfile.write(main_pid)}
|
113
|
+
end
|
114
|
+
|
115
|
+
def kill_process(pid_file)
|
116
|
+
pid = File.open(pid_file, "r") { |pid_handle| pid_handle.gets.strip.to_i }
|
117
|
+
pgid = Process.getpgid(pid)
|
118
|
+
Process.kill('-TERM', pgid)
|
119
|
+
File.delete(pid_file) if File.exists?(pid_file)
|
120
|
+
puts "Stopped BackgrounDRb worker with pid #{pid}"
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
# Free file descriptors and
|
125
|
+
# point them somewhere sensible
|
126
|
+
# STDOUT/STDERR should go to a logfile
|
127
|
+
def redirect_io(logfile_name)
|
128
|
+
begin; STDIN.reopen "/dev/null"; rescue ::Exception; end
|
129
|
+
|
130
|
+
if logfile_name
|
131
|
+
begin
|
132
|
+
STDOUT.reopen logfile_name, "a"
|
133
|
+
STDOUT.sync = true
|
134
|
+
rescue ::Exception
|
135
|
+
begin; STDOUT.reopen "/dev/null"; rescue ::Exception; end
|
136
|
+
end
|
137
|
+
else
|
138
|
+
begin; STDOUT.reopen "/dev/null"; rescue ::Exception; end
|
139
|
+
end
|
140
|
+
|
141
|
+
begin; STDERR.reopen STDOUT; rescue ::Exception; end
|
142
|
+
STDERR.sync = true
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
module BackgrounDRb
|
2
|
+
# A Worker proxy, which uses +method_missing+ for delegating method calls to the workers
|
3
|
+
class RailsWorkerProxy
|
4
|
+
attr_accessor :worker_name, :worker_method, :data, :worker_key,:middle_man
|
5
|
+
|
6
|
+
# create new worker proxy
|
7
|
+
def initialize(p_worker_name,p_worker_key = nil,p_middle_man = nil)
|
8
|
+
@worker_name = p_worker_name
|
9
|
+
@middle_man = p_middle_man
|
10
|
+
@worker_key = p_worker_key
|
11
|
+
@tried_connections = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(method_id,*args)
|
15
|
+
worker_method = method_id.to_s
|
16
|
+
arguments = args.first
|
17
|
+
|
18
|
+
arg,job_key,host_info,scheduled_at,priority = arguments && arguments.values_at(:arg,:job_key,:host,:scheduled_at, :priority)
|
19
|
+
|
20
|
+
# allow both arg and args
|
21
|
+
arg ||= arguments && arguments[:args]
|
22
|
+
|
23
|
+
new_schedule = (scheduled_at && scheduled_at.respond_to?(:utc)) ? scheduled_at.utc : Time.now.utc
|
24
|
+
|
25
|
+
if worker_method =~ /^async_(\w+)/
|
26
|
+
method_name = $1
|
27
|
+
worker_options = compact(:worker => worker_name,:worker_key => worker_key,
|
28
|
+
:worker_method => method_name,:job_key => job_key, :arg => arg)
|
29
|
+
run_method(host_info,:ask_work,worker_options)
|
30
|
+
elsif worker_method =~ /^enq_(\w+)/i
|
31
|
+
raise NoJobKey.new("Must specify a job key with enqueued tasks") if job_key.blank?
|
32
|
+
method_name = $1
|
33
|
+
marshalled_args = Marshal.dump(arg)
|
34
|
+
enqueue_task(compact(:worker_name => worker_name.to_s,:worker_key => worker_key.to_s,
|
35
|
+
:worker_method => method_name.to_s,:job_key => job_key.to_s, :priority => priority,
|
36
|
+
:args => marshalled_args,:timeout => arguments ? arguments[:timeout] : nil,:scheduled_at => new_schedule))
|
37
|
+
elsif worker_method =~ /^deq_(\w+)/i
|
38
|
+
raise NoJobKey.new("Must specify a job key to dequeue tasks") if job_key.blank?
|
39
|
+
method_name = $1
|
40
|
+
dequeue_task(compact(:worker_name => worker_name.to_s,:worker_key => worker_key.to_s,
|
41
|
+
:worker_method => method_name.to_s,:job_key => job_key.to_s))
|
42
|
+
else
|
43
|
+
worker_options = compact(:worker => worker_name,:worker_key => worker_key,
|
44
|
+
:worker_method => worker_method,:job_key => job_key,:arg => arg)
|
45
|
+
run_method(host_info,:send_request,worker_options)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# enqueue tasks to the worker pool
|
50
|
+
def enqueue_task options = {}
|
51
|
+
BdrbJobQueue.insert_job(options)
|
52
|
+
end
|
53
|
+
|
54
|
+
# remove tasks from the worker pool
|
55
|
+
def dequeue_task options = {}
|
56
|
+
BdrbJobQueue.remove_job(options)
|
57
|
+
end
|
58
|
+
|
59
|
+
# invoke method on worker
|
60
|
+
def run_method host_info,method_name,worker_options = {}
|
61
|
+
result = []
|
62
|
+
connection = choose_connection(host_info)
|
63
|
+
raise NoServerAvailable.new("No BackgrounDRb server is found running") if connection.blank?
|
64
|
+
if host_info == :local or host_info.is_a?(String)
|
65
|
+
result << invoke_on_connection(connection,method_name,worker_options)
|
66
|
+
elsif host_info == :all
|
67
|
+
succeeded = false
|
68
|
+
begin
|
69
|
+
connection.each { |conn| result << invoke_on_connection(conn,method_name,worker_options) }
|
70
|
+
succeeded = true
|
71
|
+
rescue BdrbConnError; end
|
72
|
+
raise NoServerAvailable.new("No BackgrounDRb server is found running") unless succeeded
|
73
|
+
else
|
74
|
+
@tried_connections = [connection.server_info]
|
75
|
+
begin
|
76
|
+
result << invoke_on_connection(connection,method_name,worker_options)
|
77
|
+
rescue BdrbConnError => e
|
78
|
+
connection = middle_man.find_next_except_these(@tried_connections)
|
79
|
+
@tried_connections << connection.server_info
|
80
|
+
retry
|
81
|
+
end
|
82
|
+
end
|
83
|
+
#return nil if method_name == :ask_work
|
84
|
+
process_result(return_result(result))
|
85
|
+
end
|
86
|
+
|
87
|
+
def process_result t_result
|
88
|
+
case t_result
|
89
|
+
when Hash
|
90
|
+
if(t_result[:result] == true && t_result[:type] = :response)
|
91
|
+
if(t_result[:result_flag] == "ok")
|
92
|
+
return t_result[:data]
|
93
|
+
else
|
94
|
+
raise RemoteWorkerError.new("Error while executing worker method")
|
95
|
+
end
|
96
|
+
elsif(t_result[:result_flag] == "ok")
|
97
|
+
"ok"
|
98
|
+
elsif(t_result[:result_flag] == "error")
|
99
|
+
raise RemoteWorkerError.new("Error while executing worker method")
|
100
|
+
end
|
101
|
+
when Array
|
102
|
+
t_result
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# choose a backgroundrb server connection and invoke worker method on it.
|
107
|
+
def invoke_on_connection connection,method_name,options = {}
|
108
|
+
raise NoServerAvailable.new("No BackgrounDRb is found running") unless connection
|
109
|
+
connection.send(method_name,options)
|
110
|
+
end
|
111
|
+
|
112
|
+
# get results back from the cache. Cache can be in-memory worker cache or memcache
|
113
|
+
# based cache
|
114
|
+
def ask_result job_key
|
115
|
+
options = compact(:worker => worker_name,:worker_key => worker_key,:job_key => job_key)
|
116
|
+
if BDRB_CONFIG[:backgroundrb][:result_storage] == 'memcache'
|
117
|
+
return_result_from_memcache(options)
|
118
|
+
else
|
119
|
+
result = middle_man.backend_connections.map { |conn| conn.ask_result(options) }
|
120
|
+
return_result(result)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# return runtime information about worker
|
125
|
+
def worker_info
|
126
|
+
t_connections = middle_man.backend_connections
|
127
|
+
result = t_connections.map { |conn| conn.worker_info(compact(:worker => worker_name,:worker_key => worker_key)) }
|
128
|
+
return_result(result)
|
129
|
+
end
|
130
|
+
|
131
|
+
# generate worker key
|
132
|
+
def gen_key options
|
133
|
+
key = [options[:worker],options[:worker_key],options[:job_key]].compact.join('_')
|
134
|
+
key
|
135
|
+
end
|
136
|
+
|
137
|
+
# return result from memcache
|
138
|
+
def return_result_from_memcache options = {}
|
139
|
+
middle_man.cache[gen_key(options)]
|
140
|
+
end
|
141
|
+
|
142
|
+
# reset result within memcache for given key
|
143
|
+
def reset_memcache_result(job_key,value)
|
144
|
+
options = compact(:worker => worker_name,:worker_key => worker_key,\
|
145
|
+
:job_key => job_key)
|
146
|
+
key = gen_key(options)
|
147
|
+
middle_man.cache[key] = value
|
148
|
+
value
|
149
|
+
end
|
150
|
+
|
151
|
+
def return_result result
|
152
|
+
result = Array(result)
|
153
|
+
result.size <= 1 ? result[0] : result
|
154
|
+
end
|
155
|
+
|
156
|
+
# delete a worker
|
157
|
+
def delete
|
158
|
+
middle_man.backend_connections.each do |connection|
|
159
|
+
connection.delete_worker(compact(:worker => worker_name, :worker_key => worker_key))
|
160
|
+
end
|
161
|
+
return worker_key
|
162
|
+
end
|
163
|
+
|
164
|
+
# choose a worker
|
165
|
+
def choose_connection host_info
|
166
|
+
case host_info
|
167
|
+
when :all; middle_man.backend_connections
|
168
|
+
when :local; middle_man.find_local
|
169
|
+
when String; middle_man.find_connection(host_info)
|
170
|
+
else; middle_man.choose_server
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# helper method to compact a hash and for getting rid of nil parameters
|
175
|
+
def compact(options = { })
|
176
|
+
options.delete_if { |key,value| value.nil? }
|
177
|
+
options
|
178
|
+
end
|
179
|
+
end # end of RailsWorkerProxy class
|
180
|
+
|
181
|
+
end # end of BackgrounDRb module
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Backgroundrb
|
2
|
+
# FIXME: check if data that we are writing to the socket should end with newline
|
3
|
+
require "pathname"
|
4
|
+
require "packet"
|
5
|
+
require "ostruct"
|
6
|
+
|
7
|
+
require "rails"
|
8
|
+
require "backgroundrb"
|
9
|
+
|
10
|
+
require "backgroundrb/bdrb_config"
|
11
|
+
require "backgroundrb/bdrb_client_helper"
|
12
|
+
require "backgroundrb/bdrb_job_queue"
|
13
|
+
require "backgroundrb/bdrb_conn_error"
|
14
|
+
require "backgroundrb/rails_worker_proxy"
|
15
|
+
require "backgroundrb/bdrb_connection"
|
16
|
+
require "backgroundrb/bdrb_cluster_connection"
|
17
|
+
require "backgroundrb/bdrb_start_stop"
|
18
|
+
require "backgroundrb/bdrb_result"
|
19
|
+
|
20
|
+
|
21
|
+
module BackgrounDRb
|
22
|
+
class Railtie < Rails::Railtie
|
23
|
+
config.bdrb = ActiveSupport::OrderedOptions.new
|
24
|
+
|
25
|
+
unless config.bdrb.has_key? :root
|
26
|
+
config.bdrb.root = File.expand_path(File.join(__FILE__, '..', '..', '..'))
|
27
|
+
end
|
28
|
+
BackgrounDRb::BACKGROUNDRB_ROOT = config.bdrb.root
|
29
|
+
|
30
|
+
config.before_configuration do
|
31
|
+
config_file = "#{Rails.root}/config/backgroundrb.yml"
|
32
|
+
|
33
|
+
if File.exists?(config_file) && !config.bdrb.has_key?(:config)
|
34
|
+
config.bdrb.config = BackgrounDRb::Config.read_config(config_file)
|
35
|
+
end
|
36
|
+
BackgrounDRb::BDRB_CONFIG = config.bdrb.config
|
37
|
+
|
38
|
+
MiddleMan = BackgrounDRb::ClusterConnection.new if File.exists?(config_file)
|
39
|
+
end
|
40
|
+
|
41
|
+
rake_tasks do
|
42
|
+
load "tasks/backgroundrb_tasks.rake"
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|