PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/plugins/backgroundrb/lib/backgroundrb.rb

http://tecnophoto.googlecode.com/
Ruby | 214 lines | 171 code | 26 blank | 17 comment | 7 complexity | 3c6d8a9da39fe499fb84815dc3d8642c MD5 | raw file
Possible License(s): GPL-3.0, MIT, JSON
  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. BACKGROUNDRB_ROOT = Pathname.new(RAILS_ROOT).realpath.to_s
  6. require "backgroundrb/bdrb_conn_error"
  7. require "backgroundrb/bdrb_config"
  8. require "backgroundrb/rails_worker_proxy"
  9. module BackgrounDRb
  10. end
  11. class BackgrounDRb::WorkerProxy
  12. #include Packet::NbioHelper
  13. def self.init
  14. @config = BackgrounDRb::Config.read_config("#{BACKGROUNDRB_ROOT}/config/backgroundrb.yml")
  15. @server_ip = @config[:backgroundrb][:ip]
  16. @server_port = @config[:backgroundrb][:port]
  17. new
  18. end
  19. def self.server_ip; @server_ip; end
  20. def self.server_port; @server_port; end
  21. def server_ip; self.class.server_ip; end
  22. def server_port; self.class.server_port; end
  23. def self.custom_connection(ip,port)
  24. @server_ip = ip
  25. @server_port = port
  26. new
  27. end
  28. def initialize
  29. @mutex = Mutex.new
  30. #establish_connection
  31. end
  32. def worker(worker_name,job_key = nil)
  33. BackgrounDRb::RailsWorkerProxy.worker(worker_name,job_key,self)
  34. end
  35. def establish_connection
  36. begin
  37. timeout(3) do
  38. @connection = TCPSocket.open(server_ip, server_port)
  39. @connection.setsockopt(Socket::IPPROTO_TCP,Socket::TCP_NODELAY,1)
  40. end
  41. @connection_status = true
  42. rescue Timeout::Error
  43. @connection_status = false
  44. rescue Exception => e
  45. @connection_status = false
  46. end
  47. end
  48. def write_data data
  49. begin
  50. flush_in_loop(data)
  51. rescue Errno::EAGAIN
  52. return
  53. rescue Errno::EPIPE
  54. establish_connection
  55. if @connection_status
  56. flush_in_loop(data)
  57. else
  58. @connection_status = false
  59. raise BackgrounDRb::BdrbConnError.new("Error while writing")
  60. end
  61. rescue
  62. establish_connection
  63. if @connection_status
  64. flush_in_loop(data)
  65. else
  66. @connection_status = false
  67. raise BackgrounDRb::BdrbConnError.new("Error while writing")
  68. end
  69. end
  70. end
  71. def flush_in_loop(data)
  72. t_length = data.length
  73. loop do
  74. break if t_length <= 0
  75. written_length = @connection.write(data)
  76. raise "Error writing to socket" if written_length <= 0
  77. result = @connection.flush
  78. data = data[written_length..-1]
  79. t_length = data.length
  80. end
  81. end
  82. def dump_object data
  83. establish_connection
  84. raise BackgrounDRb::BdrbConnError.new("Error while connecting to the backgroundrb server") unless @connection_status
  85. object_dump = Marshal.dump(data)
  86. dump_length = object_dump.length.to_s
  87. length_str = dump_length.rjust(9,'0')
  88. final_data = length_str + object_dump
  89. @mutex.synchronize { write_data(final_data) }
  90. end
  91. def close_connection
  92. @connection.close
  93. @connection = nil
  94. end
  95. def ask_work p_data
  96. p_data[:type] = :do_work
  97. dump_object(p_data)
  98. close_connection
  99. end
  100. def new_worker p_data
  101. p_data[:type] = :start_worker
  102. dump_object(p_data)
  103. close_connection
  104. p_data[:job_key]
  105. end
  106. def worker_info(p_data)
  107. p_data[:type] = :worker_info
  108. dump_object(p_data)
  109. bdrb_response = nil
  110. @mutex.synchronize { bdrb_response = read_from_bdrb() }
  111. close_connection
  112. bdrb_response
  113. end
  114. def all_worker_info
  115. p_data = { }
  116. p_data[:type] = :all_worker_info
  117. dump_object(p_data)
  118. bdrb_response = nil
  119. @mutex.synchronize { bdrb_response = read_from_bdrb() }
  120. close_connection
  121. bdrb_response
  122. end
  123. def delete_worker p_data
  124. p_data[:type] = :delete_worker
  125. dump_object(p_data)
  126. close_connection
  127. end
  128. def read_object
  129. begin
  130. message_length_str = @connection.read(9)
  131. message_length = message_length_str.to_i
  132. message_data = @connection.read(message_length)
  133. return message_data
  134. rescue
  135. raise BackgrounDRb::BdrbConnError.new("Not able to connect")
  136. end
  137. # begin
  138. # while(t_data = @connection.read_nonblock((16*1024)-1))
  139. # sock_data << t_data
  140. # end
  141. # return sock_data.join
  142. # rescue Errno::EAGAIN
  143. # return sock_data.join
  144. # rescue Errno::EWOULDBLOCK
  145. # return sock_data.join
  146. # rescue
  147. # raise BackgrounDRb::BdrbConnError.new("Not able to connect",sock_data.join)
  148. # end
  149. end
  150. def query_all_workers
  151. p_data = { }
  152. p_data[:type] = :all_worker_status
  153. dump_object(p_data)
  154. bdrb_response = nil
  155. @mutex.synchronize { bdrb_response = read_from_bdrb() }
  156. close_connection
  157. bdrb_response
  158. end
  159. def ask_status(p_data)
  160. p_data[:type] = :get_status
  161. dump_object(p_data)
  162. bdrb_response = nil
  163. @mutex.synchronize { bdrb_response = read_from_bdrb() }
  164. close_connection
  165. bdrb_response
  166. end
  167. def read_from_bdrb(timeout = 3)
  168. #@tokenizer = Packet::BinParser.new
  169. begin
  170. ret_val = select([@connection],nil,nil,timeout)
  171. return nil unless ret_val
  172. raw_response = read_object()
  173. master_response = Marshal.load(raw_response)
  174. return master_response
  175. rescue
  176. return nil
  177. end
  178. end
  179. def send_request(p_data)
  180. p_data[:type] = :get_result
  181. dump_object(p_data)
  182. bdrb_response = nil
  183. @mutex.synchronize { bdrb_response = read_from_bdrb(nil) }
  184. close_connection
  185. bdrb_response
  186. end
  187. end
  188. MiddleMan = BackgrounDRb::WorkerProxy.init