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,17 @@
1
+ # Put your code that runs your task inside the do_work method it will be
2
+ # run automatically in a thread. You have access to all of your rails
3
+ # models. You also get logger and results method inside of this class
4
+ # by default.
5
+ class ErrorWorker < BackgrounDRb::MetaWorker
6
+ set_worker_name :error_worker
7
+ set_no_auto_load(true)
8
+
9
+ def create(args = nil)
10
+ logger.info "creating error worker"
11
+ end
12
+
13
+ def hello_world(data)
14
+ logger.info "invoking #{worker_name} hello world #{data} #{Time.now}"
15
+ end
16
+ end
17
+
@@ -0,0 +1,38 @@
1
+ # Put your code that runs your task inside the do_work method it will be
2
+ # run automatically in a thread. You have access to all of your rails
3
+ # models. You also get logger and results method inside of this class
4
+ # by default.
5
+
6
+ class TimeClient
7
+ def receive_data(p_data)
8
+ worker.get_external_data(p_data)
9
+ end
10
+
11
+ def post_init
12
+ p "***************** : connection completed"
13
+ end
14
+ end
15
+
16
+ class FooWorker < BackgrounDRb::MetaWorker
17
+ set_worker_name :foo_worker
18
+ def create(args = nil)
19
+ #register_status("Running")
20
+ add_periodic_timer(10) { foobar }
21
+ external_connection = nil
22
+ connect("localhost",11009,TimeClient) { |conn| external_connection = conn }
23
+ end
24
+
25
+ def get_external_data(p_data)
26
+ cache[some_key] = p_data
27
+ end
28
+
29
+ def foobar
30
+ cache[some_key] = "Time is now : #{Time.now}"
31
+ end
32
+
33
+ def barbar(data)
34
+ logger.info "invoking babrbar on #{Time.now} #{data}"
35
+ end
36
+
37
+ end
38
+
@@ -0,0 +1,7 @@
1
+ class GodWorker < BackgrounDRb::MetaWorker
2
+ set_worker_name :god_worker
3
+ def create(args = nil)
4
+ logger.info "hello world"
5
+ end
6
+ end
7
+
@@ -0,0 +1,13 @@
1
+ class ModelWorker < BackgrounDRb::MetaWorker
2
+ set_worker_name :model_worker
3
+ def create(args = nil)
4
+ #add_periodic_timer(2) { add_new_user }
5
+ end
6
+
7
+ def add_new_user
8
+ login,age = "Hemant: #{Time.now}",rand(24)
9
+ logger.info "creating user #{login} with age #{age}"
10
+ User.create(:login => login, :age => age)
11
+ end
12
+ end
13
+
@@ -0,0 +1,11 @@
1
+ class RenewalWorker < BackgrounDRb::MetaWorker
2
+ set_worker_name :renewal_worker
3
+ def create(args = nil)
4
+
5
+ end
6
+ def load_policies(data = nil)
7
+ logger.info "Loading policies done on #{data}"
8
+ return "done"
9
+ end
10
+ end
11
+
@@ -0,0 +1,26 @@
1
+ # this worker would test thread issues that were discussed before
2
+ require "net/http"
3
+ class RssWorker < BackgrounDRb::MetaWorker
4
+ set_worker_name :rss_worker
5
+ def create(args = nil)
6
+ # this method is called, when worker is loaded for the first time
7
+ end
8
+
9
+ # method would fetch supplied urls in a thread
10
+ def fetch_url(url)
11
+ puts "fetching url #{url}"
12
+ thread_pool.defer(:scrap_things,url)
13
+ end
14
+
15
+ def scrap_things url
16
+ begin
17
+ data = Net::HTTP.get(url,"/")
18
+ File.open("#{RAILS_ROOT}/log/pages.txt","w") do |fl|
19
+ fl.puts(data)
20
+ end
21
+ rescue
22
+ logger.info "Error downloading page"
23
+ end
24
+ end
25
+ end
26
+
@@ -0,0 +1,31 @@
1
+ class TimeServer
2
+ # the data send by client would be received here
3
+ def receive_data(p_data)
4
+ end
5
+
6
+ # would be called when someone connects to the server for the
7
+ # first time
8
+ def post_init
9
+ add_periodic_timer(2) { say_hello_world }
10
+ end
11
+
12
+ # would be called when client connection is complete.
13
+ def connection_completed
14
+ end
15
+
16
+ def say_hello_world
17
+ send_data("Hello World\n")
18
+ end
19
+ end
20
+
21
+ # this worker is going to act like server.
22
+ class ServerWorker < BackgrounDRb::MetaWorker
23
+ set_worker_name :server_worker
24
+ def create(args = nil)
25
+ # start the server when worker starts
26
+ start_server("0.0.0.0",11009,TimeServer) do |client_connection|
27
+ client_connection.say_hello_world
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,12 @@
1
+ class WorldWorker < BackgrounDRb::MetaWorker
2
+ set_worker_name :world_worker
3
+ def create(args = nil)
4
+ #logger.info "starting world worker"
5
+ end
6
+
7
+ def hello_world
8
+ a = lambda { "Hello world" }
9
+ return a
10
+ end
11
+ end
12
+
@@ -0,0 +1,7 @@
1
+ class XmppWorker < BackgrounDRb::MetaWorker
2
+ set_worker_name :xmpp_worker
3
+ def create(args = nil)
4
+ # this method is called, when worker is loaded for the first time
5
+ end
6
+ end
7
+
data/init.rb ADDED
@@ -0,0 +1,7 @@
1
+ # Include hook code here
2
+ %w{ controller }.each do |code_dir|
3
+ $:.unshift File.join(File.dirname(__FILE__),"app",code_dir)
4
+ end
5
+
6
+ require 'backgroundrb'
7
+ #require "backgroundrb_status_controller"
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here
data/know_issues.org ADDED
@@ -0,0 +1,5 @@
1
+ * Some issues that I am aware of *
2
+ - Creation of job queue may fail on other that mysql dbs
3
+ - Database doesn't get created when someone runs the migrations again
4
+ - Delete doesn't seem to be working test it.
5
+
@@ -0,0 +1 @@
1
+ require "backgroundrb/railtie"
@@ -0,0 +1,8 @@
1
+ module BackgrounDRb
2
+ module ClientHelper
3
+ def gen_worker_key(worker_name,worker_key = nil)
4
+ return worker_name.to_sym if worker_key.nil?
5
+ return "#{worker_name}_#{worker_key}".to_sym
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,156 @@
1
+ # class stores connections to BackgrounDRb servers in a cluster manner
2
+ module BackgrounDRb
3
+ class ClusterConnection
4
+ include ClientHelper
5
+ attr_accessor :backend_connections,:config,:cache,:bdrb_servers
6
+ attr_accessor :disconnected_connections
7
+
8
+ # initialize cluster connection
9
+ def initialize
10
+ @bdrb_servers = []
11
+ @backend_connections = []
12
+ @disconnected_connections = {}
13
+
14
+ @last_polled_time = Time.now
15
+ @request_count = 0
16
+
17
+ initialize_memcache if BackgrounDRb::BDRB_CONFIG[:backgroundrb][:result_storage] == 'memcache'
18
+ establish_connections
19
+ @round_robin = (0...@backend_connections.length).to_a
20
+ end
21
+
22
+ # initialize memache if client is storing results in memcache
23
+ def initialize_memcache
24
+ require 'memcache'
25
+ memcache_options = {
26
+ :c_threshold => 10_000,
27
+ :compression => true,
28
+ :debug => false,
29
+ :namespace => 'backgroundrb_result_hash',
30
+ :readonly => false,
31
+ :urlencode => false
32
+ }
33
+ @cache = MemCache.new(memcache_options)
34
+ @cache.servers = BackgrounDRb::BDRB_CONFIG[:memcache].split(',')
35
+ end
36
+
37
+ # initialize all backend server connections
38
+ def establish_connections
39
+ klass = Struct.new(:ip,:port)
40
+ if t_servers = BackgrounDRb::BDRB_CONFIG[:client]
41
+ connections = t_servers.split(',')
42
+ connections.each do |conn_string|
43
+ ip = conn_string.split(':')[0]
44
+ port = conn_string.split(':')[1].to_i
45
+ @bdrb_servers << klass.new(ip,port)
46
+ end
47
+ end
48
+ @bdrb_servers << klass.new(BackgrounDRb::BDRB_CONFIG[:backgroundrb][:ip],BackgrounDRb::BDRB_CONFIG[:backgroundrb][:port].to_i)
49
+ @bdrb_servers.each_with_index do |connection_info,index|
50
+ next if @backend_connections.detect { |x| x.server_info == "#{connection_info.ip}:#{connection_info.port}" }
51
+ @backend_connections << Connection.new(connection_info.ip,connection_info.port,self)
52
+ end
53
+ end # end of method establish_connections
54
+
55
+ # every 10 request or 10 seconds it will try to reconnect to bdrb servers which were down
56
+ def discover_server_periodically
57
+ @disconnected_connections.each do |key,connection|
58
+ connection.establish_connection
59
+ if connection.connection_status
60
+ @backend_connections << connection
61
+ connection.close_connection
62
+ @disconnected_connections[key] = nil
63
+ end
64
+ end
65
+ @disconnected_connections.delete_if { |key,value| value.nil? }
66
+ @round_robin = (0...@backend_connections.length).to_a
67
+ end
68
+
69
+ # Find live connections except those mentioned in array, because they
70
+ # are already dead.
71
+ def find_next_except_these connections
72
+ invalid_connections = @backend_connections.select { |x| connections.include?(x.server_info) }
73
+ @backend_connections.delete_if { |x| connections.include?(x.server_info) }
74
+ @round_robin = (0...@backend_connections.length).to_a
75
+ invalid_connections.each do |x|
76
+ @disconnected_connections[x.server_info] = x
77
+ end
78
+ chosen = @backend_connections.detect { |x| !(connections.include?(x.server_info)) }
79
+ raise NoServerAvailable.new("No BackgrounDRb server is found running") unless chosen
80
+ chosen
81
+ end
82
+
83
+ # Fina a connection by host name and port
84
+ def find_connection host_info
85
+ conn = @backend_connections.detect { |x| x.server_info == host_info }
86
+ raise NoServerAvailable.new("BackgrounDRb server is not found running on #{host_info}") unless conn
87
+ return conn
88
+ end
89
+
90
+ # find the local configured connection
91
+ def find_local
92
+ find_connection("#{BackgrounDRb::BDRB_CONFIG[:backgroundrb][:ip]}:#{BackgrounDRb::BDRB_CONFIG[:backgroundrb][:port]}")
93
+ end
94
+
95
+ # return the worker proxy
96
+ def worker(worker_name,worker_key = nil)
97
+ update_stats
98
+ RailsWorkerProxy.new(worker_name,worker_key,self)
99
+ end
100
+
101
+ # Update the stats and discover new nodes if they came up.
102
+ def update_stats
103
+ @request_count += 1
104
+ discover_server_periodically if(time_to_discover? && !@disconnected_connections.empty?)
105
+ end
106
+
107
+ # Check if, we should try to discover new bdrb servers
108
+ def time_to_discover?
109
+ if((@request_count%10 == 0) or (Time.now > (@last_polled_time + 10.seconds)))
110
+ @last_polled_time = Time.now
111
+ return true
112
+ else
113
+ return false
114
+ end
115
+ end
116
+
117
+ # Send worker information of all currently running workers from all configured bdrb
118
+ # servers
119
+ def all_worker_info
120
+ update_stats
121
+ info_data = {}
122
+ @backend_connections.each do |t_connection|
123
+ info_data[t_connection.server_info] = t_connection.all_worker_info rescue nil
124
+ end
125
+ return info_data
126
+ end
127
+
128
+ # one of the backend connections are chosen and worker is started on it
129
+ def new_worker(options = {})
130
+ update_stats
131
+ succeeded = false
132
+ result = nil
133
+
134
+ @backend_connections.each do |connection|
135
+ begin
136
+ result = connection.new_worker(options)
137
+ succeeded = true
138
+ rescue BdrbConnError; end
139
+ end
140
+ raise NoServerAvailable.new("No BackgrounDRb server is found running") unless succeeded
141
+ return options[:worker_key]
142
+ end
143
+
144
+ # choose a server in round robin manner.
145
+ def choose_server
146
+ if @round_robin.empty?
147
+ @round_robin = (0...@backend_connections.length).to_a
148
+ end
149
+ if @round_robin.empty? && @backend_connections.empty?
150
+ discover_server_periodically
151
+ raise NoServerAvailable.new("No BackgrounDRb server is found running") if @round_robin.empty? && @backend_connections.empty?
152
+ end
153
+ @backend_connections[@round_robin.shift]
154
+ end
155
+ end # end of ClusterConnection
156
+ end # end of Module BackgrounDRb
@@ -0,0 +1,43 @@
1
+ require 'yaml'
2
+ require 'erb'
3
+ module BackgrounDRb
4
+ class Config
5
+ def self.parse_cmd_options(argv)
6
+ options = { }
7
+
8
+ OptionParser.new do |opts|
9
+ script_name = File.basename($0)
10
+ opts.banner = "Usage: #{$0} [options]"
11
+ opts.separator ""
12
+ opts.on("-e", "--environment=name", String,
13
+ "Specifies the environment to operate under (test/development/production).",
14
+ "Default: development") { |v| options[:environment] = v }
15
+ opts.separator ""
16
+ opts.on("-h", "--help",
17
+ "Show this help message.") { $stderr.puts opts; exit }
18
+ opts.separator ""
19
+ opts.on("-v","--version",
20
+ "Show version.") { $stderr.puts "1.1"; exit }
21
+ end.parse!(argv)
22
+
23
+ ENV["RAILS_ENV"] = options[:environment] if options[:environment]
24
+ end
25
+
26
+ def self.read_config(config_file)
27
+ config = YAML.load(ERB.new(IO.read(config_file)).result)
28
+ environment = ENV["RAILS_ENV"] || config[:backgroundrb][:environment] || "development"
29
+
30
+ if respond_to?(:silence_warnings)
31
+ silence_warnings do
32
+ Object.const_set("RAILS_ENV",environment)
33
+ end
34
+ else
35
+ Object.const_set("RAILS_ENV",environment)
36
+ end
37
+
38
+ ENV["RAILS_ENV"] = environment
39
+ config
40
+ end
41
+ end
42
+ end
43
+
@@ -0,0 +1,29 @@
1
+ # Exception class for BackgrounDRb connection errors
2
+ module BackgrounDRb
3
+ # raised when connection to a particular server failed
4
+ class BdrbConnError < RuntimeError
5
+ attr_accessor :message
6
+ def initialize(message)
7
+ @message = message
8
+ end
9
+ end
10
+ # raised when connection to all of the available servers failed
11
+ class NoServerAvailable < RuntimeError
12
+ attr_accessor :message
13
+ def initialize(message)
14
+ @message = message
15
+ end
16
+ end
17
+
18
+ # raised, when said task was submitted without a job key, whereas
19
+ # nature of the task requires a job key
20
+ class NoJobKey < RuntimeError; end
21
+
22
+ # raised if worker throws some error
23
+ class RemoteWorkerError < RuntimeError
24
+ attr_accessor :message
25
+ def initialize message
26
+ @message = message
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,179 @@
1
+ module BackgrounDRb
2
+ class Connection
3
+ attr_accessor :server_ip,:server_port,:cluster_conn,:connection_status
4
+
5
+ def initialize ip,port,cluster_conn
6
+ @mutex = Mutex.new
7
+ @server_ip = ip
8
+ @server_port = port
9
+ @cluster_conn = cluster_conn
10
+ @connection_status = true
11
+ end
12
+
13
+
14
+ def establish_connection
15
+ begin
16
+ timeout(3) do
17
+ @connection = TCPSocket.open(server_ip, server_port)
18
+ @connection.setsockopt(Socket::IPPROTO_TCP,Socket::TCP_NODELAY,1)
19
+ end
20
+ @connection_status = true
21
+ rescue Timeout::Error
22
+ @connection_status = false
23
+ rescue Exception => e
24
+ @connection_status = false
25
+ end
26
+ end
27
+
28
+ def write_data data
29
+ begin
30
+ flush_in_loop(data)
31
+ rescue Errno::EAGAIN
32
+ return
33
+ rescue Errno::EPIPE
34
+ establish_connection
35
+ if @connection_status
36
+ flush_in_loop(data)
37
+ else
38
+ @connection_status = false
39
+ raise BackgrounDRb::BdrbConnError.new("Error while writing #{server_info}")
40
+ end
41
+ rescue
42
+ establish_connection
43
+ if @connection_status
44
+ flush_in_loop(data)
45
+ else
46
+ @connection_status = false
47
+ raise BackgrounDRb::BdrbConnError.new("Error while writing #{server_info}")
48
+ end
49
+ end
50
+ end
51
+
52
+ def server_info
53
+ "#{server_ip}:#{server_port}"
54
+ end
55
+
56
+ def flush_in_loop(data)
57
+ t_length = data.length
58
+ loop do
59
+ break if t_length <= 0
60
+ written_length = @connection.write(data)
61
+ raise "Error writing to socket" if written_length <= 0
62
+ result = @connection.flush
63
+ data = data[written_length..-1]
64
+ t_length = data.length
65
+ end
66
+ end
67
+
68
+ def dump_object data
69
+ establish_connection
70
+ raise BackgrounDRb::BdrbConnError.new("Error while connecting to the backgroundrb server #{server_info}") unless @connection_status
71
+
72
+ object_dump = Marshal.dump(data)
73
+ dump_length = object_dump.length.to_s
74
+ length_str = dump_length.rjust(9,'0')
75
+ final_data = length_str + object_dump
76
+ @mutex.synchronize { write_data(final_data) }
77
+ end
78
+
79
+ def close_connection
80
+ @connection.close
81
+ @connection = nil
82
+ end
83
+
84
+ def ask_work p_data
85
+ p_data[:type] = :async_invoke
86
+ dump_object(p_data)
87
+ bdrb_response = nil
88
+ @mutex.synchronize { bdrb_response = read_from_bdrb() }
89
+ close_connection
90
+ bdrb_response
91
+ end
92
+
93
+ def new_worker p_data
94
+ p_data[:type] = :start_worker
95
+ dump_object(p_data)
96
+ close_connection
97
+ # RailsWorkerProxy.worker(p_data[:worker],p_data[:worker_key],self)
98
+ end
99
+
100
+ def worker_info(p_data)
101
+ p_data[:type] = :worker_info
102
+ dump_object(p_data)
103
+ bdrb_response = nil
104
+ @mutex.synchronize { bdrb_response = read_from_bdrb() }
105
+ close_connection
106
+ bdrb_response
107
+ end
108
+
109
+ def all_worker_info
110
+ p_data = { }
111
+ p_data[:type] = :all_worker_info
112
+ dump_object(p_data)
113
+ bdrb_response = nil
114
+ @mutex.synchronize { bdrb_response = read_from_bdrb() }
115
+ close_connection
116
+ bdrb_response
117
+ end
118
+
119
+ def delete_worker p_data
120
+ p_data[:type] = :delete_worker
121
+ dump_object(p_data)
122
+ close_connection
123
+ end
124
+
125
+ def read_object
126
+ begin
127
+ message_length_str = @connection.read(9)
128
+ message_length = message_length_str.to_i
129
+ message_data = @connection.read(message_length)
130
+ return message_data
131
+ rescue
132
+ raise BackgrounDRb::BdrbConnError.new("Not able to connect #{server_info}")
133
+ end
134
+ end
135
+
136
+ def gen_key options
137
+ if BDRB_CONFIG[:backgroundrb][:result_storage] == 'memcache'
138
+ key = [options[:worker],options[:worker_key],options[:job_key]].compact.join('_')
139
+ key
140
+ else
141
+ options[:job_key]
142
+ end
143
+ end
144
+
145
+ def ask_result(p_data)
146
+ if BDRB_CONFIG[:backgroundrb][:result_storage] == 'memcache'
147
+ return_result_from_memcache(p_data)
148
+ else
149
+ p_data[:type] = :get_result
150
+ dump_object(p_data)
151
+ bdrb_response = nil
152
+ @mutex.synchronize { bdrb_response = read_from_bdrb() }
153
+ close_connection
154
+ bdrb_response ? bdrb_response[:data] : nil
155
+ end
156
+ end
157
+
158
+ def read_from_bdrb(timeout = 3)
159
+ begin
160
+ ret_val = select([@connection],nil,nil,timeout)
161
+ return nil unless ret_val
162
+ raw_response = read_object()
163
+ master_response = Marshal.load(raw_response)
164
+ return master_response
165
+ rescue
166
+ return nil
167
+ end
168
+ end
169
+
170
+ def send_request(p_data)
171
+ p_data[:type] = :sync_invoke
172
+ dump_object(p_data)
173
+ bdrb_response = nil
174
+ @mutex.synchronize { bdrb_response = read_from_bdrb(nil) }
175
+ close_connection
176
+ bdrb_response
177
+ end
178
+ end
179
+ end