ruby_process 0.0.9 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,11 +1,11 @@
1
- class Ruby_process
1
+ class RubyProcess
2
2
  #Evalulates the given string in the process.
3
3
  #===Examples
4
4
  # rp.str_eval("return 10").__rp_marshal #=> 10
5
5
  def str_eval(str)
6
- send(:cmd => :str_eval, :str => str)
6
+ send(cmd: :str_eval, str: str)
7
7
  end
8
-
8
+
9
9
  #Process-method for 'str_eval'.
10
10
  def cmd_str_eval(obj)
11
11
  #Lamda is used here because 'return' might be used in evalled code and thereby return an unhandeled object.
@@ -13,4 +13,4 @@ class Ruby_process
13
13
  eval(obj[:str])
14
14
  }.call)
15
15
  end
16
- end
16
+ end
@@ -1,9 +1,9 @@
1
- class Ruby_process
1
+ class RubyProcess
2
2
  #Closes the process by executing exit.
3
3
  def cmd_exit(obj)
4
4
  exit
5
5
  end
6
-
6
+
7
7
  #Flushes various collected object-IDs to the subprocess, where they will be garbage-collected.
8
8
  def flush_finalized
9
9
  @flush_mutex.synchronize do
@@ -11,37 +11,37 @@ class Ruby_process
11
11
  ids = @proxy_objs_unsets.shift(500)
12
12
  debug "IDS: #{ids} #{@proxy_objs_unsets}\n" if @debug
13
13
  return nil if ids.empty?
14
-
14
+
15
15
  debug "Ruby-process-debug: Finalizing (#{ids}).\n" if @debug
16
- send(:cmd => :flush_finalized, :ids => ids)
16
+ send(cmd: :flush_finalized, ids: ids)
17
17
  @finalize_count += ids.length
18
18
  return nil
19
19
  end
20
20
  end
21
-
21
+
22
22
  #Flushes references to the given object IDs.
23
23
  def cmd_flush_finalized(obj)
24
24
  debug "Command-flushing finalized: '#{obj[:ids]}'.\n" if @debug
25
25
  obj[:ids].each do |id|
26
- raise "Unknown ID: '#{id}' (#{id.class.name})." if !@objects.key?(id)
26
+ raise "Unknown ID: '#{id}' (#{id.class.name})." unless @objects.key?(id)
27
27
  @objects.delete(id)
28
28
  end
29
-
29
+
30
30
  return nil
31
31
  end
32
-
32
+
33
33
  #Starts garbage-collecting and then flushes the finalized objects to the sub-process. Does the same thing in the sub-process.
34
34
  def garbage_collect
35
35
  GC.start
36
36
  self.flush_finalized
37
- send(:cmd => :garbage_collect)
37
+ send(cmd: :garbage_collect)
38
38
  return nil
39
39
  end
40
-
40
+
41
41
  #The sub-process-side execution of 'garbage_collect'.
42
42
  def cmd_garbage_collect(obj)
43
43
  GC.start
44
44
  self.flush_finalized
45
45
  return nil
46
46
  end
47
- end
47
+ end
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require "ruby_process"
5
+
6
+ RubyProcess.new.spawn_process do |rp|
7
+ rp.static(:Object, :require, "csv")
8
+
9
+ rp.static(:CSV, :open, "test.csv", "w") do |csv|
10
+ csv << ["ID", "Name"]
11
+ csv << [1, "Kasper"]
12
+ end
13
+ end
@@ -4,7 +4,7 @@ require "rubygems"
4
4
  require "ruby_process"
5
5
 
6
6
  fpath = "/tmp/somefile"
7
- Ruby_process.new.spawn_process do |rp|
7
+ RubyProcess.new.spawn_process do |rp|
8
8
  #Opens file in subprocess.
9
9
  rp.static(:File, :open, fpath, "w") do |fp|
10
10
  #Writes to file in subprocess.
@@ -12,4 +12,4 @@ Ruby_process.new.spawn_process do |rp|
12
12
  end
13
13
  end
14
14
 
15
- print "Content of '#{fpath}': #{File.read(fpath)}\n"
15
+ print "Content of '#{fpath}': #{File.read(fpath)}\n"
@@ -23,17 +23,17 @@ threads = []
23
23
  threads << Thread.new do
24
24
  begin
25
25
  thread_tables = tables.shift(tables_per_thread)
26
-
27
- Ruby_process.new(:debug => true).spawn_process do |rp|
26
+
27
+ RubyProcess.new(debug: true).spawn_process do |rp|
28
28
  rp.static(:Object, :require, "rubygems")
29
29
  rp.static(:Object, :require, "knjrbfw")
30
-
30
+
31
31
  fpath = "/tmp/dbdump_#{i}.sql"
32
-
32
+
33
33
  thread_tables.each do |thread_db|
34
34
  rp_db = rp.new("Knj::Db", $db_settings)
35
- rp_dump = rp.new("Knj::Db::Dump", :db => rp_db, :tables => thread_tables)
36
-
35
+ rp_dump = rp.new("Knj::Db::Dump", db: rp_db, tables: thread_tables)
36
+
37
37
  rp.static(:File, :open, fpath, "w") do |rp_fp|
38
38
  print "#{i} dumping #{thread_db}\n"
39
39
  rp_dump.dump(rp_fp)
@@ -49,4 +49,4 @@ end
49
49
 
50
50
  threads.each do |thread|
51
51
  thread.join
52
- end
52
+ end
@@ -3,12 +3,12 @@
3
3
  require "rubygems"
4
4
  require "ruby_process"
5
5
 
6
- Ruby_process.new.spawn_process do |rp|
6
+ RubyProcess.new.spawn_process do |rp|
7
7
  #Spawns string in the subprocess.
8
8
  str = rp.new(:String, "Kasper is 26 years old")
9
-
9
+
10
10
  #Scans with regex in subprocess, but yields proxy-objects in the current process.
11
11
  str.scan(/is (\d+) years old/) do |match|
12
12
  puts match.__rp_marshal
13
13
  end
14
- end
14
+ end
@@ -1,4 +1,4 @@
1
- class Ruby_process
1
+ class RubyProcess
2
2
  #Recursivly parses arrays and hashes into proxy-object-hashes.
3
3
  def parse_args(args)
4
4
  if args.is_a?(Array)
@@ -6,14 +6,14 @@ class Ruby_process
6
6
  args.each do |val|
7
7
  newarr << parse_args(val)
8
8
  end
9
-
9
+
10
10
  return newarr
11
11
  elsif args.is_a?(Hash)
12
12
  newh = {}
13
13
  args.each do |key, val|
14
14
  newh[parse_args(key)] = parse_args(val)
15
15
  end
16
-
16
+
17
17
  return newh
18
18
  elsif @args_allowed.index(args.class) != nil
19
19
  debug "Allowing type '#{args.class}' as an argument: '#{args}'.\n" if @debug
@@ -23,38 +23,38 @@ class Ruby_process
23
23
  return handle_return_object(args)
24
24
  end
25
25
  end
26
-
27
- private
28
-
26
+
27
+ private
28
+
29
29
  #Returns a special hash instead of an actual object. Some objects will be returned in their normal form (true, false and nil).
30
30
  def handle_return_object(obj, pid = @my_pid)
31
31
  #Dont proxy these objects.
32
32
  return obj if obj.is_a?(TrueClass) or obj.is_a?(FalseClass) or obj.is_a?(NilClass)
33
-
33
+
34
34
  #The object is a proxy-obj - just return its arguments that contains the true 'my_pid'.
35
- if obj.is_a?(Ruby_process::Proxyobj)
35
+ if obj.is_a?(RubyProcess::ProxyObject)
36
36
  debug "Returning from proxy-obj: (ID: #{obj.args[:id]}, PID: #{obj.__rp_pid}).\n" if @debug
37
- return {:type => :proxy_obj, :id => obj.__rp_id, :pid => obj.__rp_pid}
37
+ return {type: :proxy_obj, id: obj.__rp_id, pid: obj.__rp_pid}
38
38
  end
39
-
39
+
40
40
  #Check if object has already been spawned. If not: spawn id. Then returns hash for it.
41
41
  id = obj.__id__
42
42
  @objects[id] = obj if !@objects.key?(id)
43
-
43
+
44
44
  debug "Proxy-object spawned (ID: #{id}, PID: #{pid}).\n" if @debug
45
- return {:type => :proxy_obj, :id => id, :pid => pid}
45
+ return {type: :proxy_obj, id: id, pid: pid}
46
46
  end
47
-
47
+
48
48
  #Parses an argument array to proxy-object-hashes.
49
49
  def handle_return_args(arr)
50
50
  newa = []
51
51
  arr.each do |obj|
52
52
  newa << handle_return_object(obj)
53
53
  end
54
-
54
+
55
55
  return newa
56
56
  end
57
-
57
+
58
58
  #Recursivly scans arrays and hashes for proxy-object-hashes and replaces them with actual proxy-objects.
59
59
  def read_args(args)
60
60
  if args.is_a?(Array)
@@ -62,11 +62,11 @@ class Ruby_process
62
62
  args.each do |val|
63
63
  newarr << read_args(val)
64
64
  end
65
-
65
+
66
66
  return newarr
67
- elsif args.is_a?(Hash) and args.length == 3 and args[:type] == :proxy_obj and args.key?(:id) and args.key?(:pid)
67
+ elsif args.is_a?(Hash) && args.length == 3 && args[:type] == :proxy_obj && args.key?(:id) && args.key?(:pid)
68
68
  debug "Comparing PID (#{args[:pid]}, #{@my_pid}).\n" if @debug
69
-
69
+
70
70
  if args[:pid] == @my_pid
71
71
  debug "Same!\n" if @debug
72
72
  return proxyobj_object(args[:id])
@@ -79,10 +79,10 @@ class Ruby_process
79
79
  args.each do |key, val|
80
80
  newh[read_args(key)] = read_args(val)
81
81
  end
82
-
82
+
83
83
  return newh
84
84
  end
85
-
85
+
86
86
  return args
87
87
  end
88
- end
88
+ end
@@ -1,79 +1,85 @@
1
1
  require "rubygems"
2
- require "wref" if !Kernel.const_defined?(:Wref)
3
- require "tsafe" if !Kernel.const_defined?(:Tsafe)
2
+ require "wref" unless Kernel.const_defined?(:Wref)
3
+ require "tsafe" unless Kernel.const_defined?(:Tsafe)
4
4
  require "base64"
5
+ require "string-cases"
5
6
  require "thread"
6
7
  require "timeout"
7
8
 
8
9
  #This class can communicate with another Ruby-process. It tries to integrate the work in the other process as seamless as possible by using proxy-objects.
9
- class Ruby_process
10
+ class RubyProcess
10
11
  attr_reader :finalize_count, :pid
11
-
12
+
12
13
  #Require all the different commands.
13
14
  dir = "#{File.dirname(__FILE__)}/../cmds"
14
15
  Dir.foreach(dir) do |file|
15
16
  require "#{dir}/#{file}" if file =~ /\.rb$/
16
17
  end
17
-
18
+
18
19
  #Methods for handeling arguments and proxy-objects in arguments.
19
20
  require "#{File.dirname(__FILE__)}/../include/args_handeling.rb"
20
-
21
+
21
22
  #Autoloader for subclasses.
22
23
  def self.const_missing(name)
23
- require "#{File.realpath(File.dirname(__FILE__))}/ruby_process_#{name.to_s.downcase}.rb"
24
- raise "Still not defined: '#{name}'." if !self.const_defined?(name)
25
- return self.const_get(name)
24
+ file_path = "#{::File.realpath(::File.dirname(__FILE__))}/ruby_process/#{::StringCases.camel_to_snake(name)}.rb"
25
+
26
+ if File.exists?(file_path)
27
+ require file_path
28
+ return const_get(name) if const_defined?(name)
29
+ end
30
+
31
+ super
26
32
  end
27
-
33
+
28
34
  #Constructor.
29
35
  #===Examples
30
- # Ruby_process.new.spawn_process do |rp|
36
+ # RubyProcess.new.spawn_process do |rp|
31
37
  # str = rp.new(:String, "Kasper")
32
38
  # end
33
39
  def initialize(args = {})
34
40
  @args = args
35
41
  @debug = @args[:debug]
36
42
  @pid = @args[:pid]
37
-
43
+
38
44
  #These classes are allowed in call-arguments. They can be marshalled without any errors.
39
45
  @args_allowed = [FalseClass, Fixnum, Integer, NilClass, String, Symbol, TrueClass]
40
-
46
+
41
47
  #Set IO variables if given.
42
- @io_out = Tsafe::Proxy.new(:obj => @args[:out]) if @args[:out]
48
+ @io_out = Tsafe::Proxy.new(obj: @args[:out]) if @args[:out]
43
49
  @io_in = @args[:in] if @args[:in]
44
50
  @io_err = @args[:err] if @args[:err]
45
-
51
+
46
52
  #This hash holds answers coming from the subprocess.
47
53
  @answers = Tsafe::MonHash.new
48
-
54
+
49
55
  #This hash holds objects that are referenced in the process.
50
56
  @objects = Tsafe::MonHash.new
51
-
57
+
52
58
  #This weak-map holds all proxy objects.
53
59
  @proxy_objs = Wref_map.new
54
60
  @proxy_objs_ids = Tsafe::MonHash.new
55
61
  @proxy_objs_unsets = Tsafe::MonArray.new
56
62
  @flush_mutex = Mutex.new
57
63
  @finalize_count = 0
58
-
64
+
59
65
  #Send ID is used to identify the correct answers.
60
66
  @send_mutex = Mutex.new
61
67
  @send_count = 0
62
-
68
+
63
69
  #The PID is used to know which process proxy-objects belongs to.
64
70
  @my_pid = Process.pid
65
71
  end
66
-
72
+
67
73
  #Spawns a new process in the same Ruby-inteterpeter as the current one.
68
74
  #===Examples
69
- # rp = Ruby_process.new.spawn_process
75
+ # rp = RubyProcess.new.spawn_process
70
76
  # rp.str_eval("return 10").__rp_marshal #=> 10
71
77
  # rp.destroy
72
78
  def spawn_process(args = nil)
73
79
  #Used for printing debug-stuff.
74
80
  @main = true
75
-
76
- if args and args[:exec]
81
+
82
+ if args && args[:exec]
77
83
  cmd = "#{args[:exec]}"
78
84
  else
79
85
  if !ENV["rvm_ruby_string"].to_s.empty?
@@ -82,82 +88,82 @@ class Ruby_process
82
88
  cmd = "ruby"
83
89
  end
84
90
  end
85
-
91
+
86
92
  cmd << " \"#{File.realpath(File.dirname(__FILE__))}/../scripts/ruby_process_script.rb\" --pid=#{@my_pid}"
87
93
  cmd << " --debug" if @args[:debug]
88
94
  cmd << " \"--title=#{@args[:title]}\"" if !@args[:title].to_s.strip.empty?
89
-
95
+
90
96
  #Start process and set IO variables.
91
97
  require "open3"
92
98
  @io_out, @io_in, @io_err = Open3.popen3(cmd)
93
- @io_out = Tsafe::Proxy.new(:obj => @io_out)
99
+ @io_out = Tsafe::Proxy.new(obj: @io_out)
94
100
  @io_out.sync = true
95
101
  @io_in.sync = true
96
102
  @io_err.sync = true
97
-
103
+
98
104
  started = false
99
105
  @io_in.each_line do |str|
100
106
  if str == "ruby_process_started\n"
101
107
  started = true
102
108
  break
103
109
  end
104
-
110
+
105
111
  debug "Ruby-process-debug from stdout before started: '#{str}'\n" if @debug
106
112
  end
107
-
108
- raise "Ruby-sub-process couldnt start: '#{@io_err.read}'." if !started
113
+
114
+ raise "Ruby-sub-process couldnt start: '#{@io_err.read}'." unless started
109
115
  self.listen
110
-
116
+
111
117
  #Start by getting the PID of the process.
112
118
  begin
113
119
  @pid = self.static(:Process, :pid).__rp_marshal
114
- raise "Unexpected PID: '#{@pid}'." if !@pid.is_a?(Fixnum) and !@pid.is_a?(Integer)
120
+ raise "Unexpected PID: '#{@pid}'." if !@pid.is_a?(Fixnum) && !@pid.is_a?(Integer)
115
121
  rescue => e
116
122
  self.destroy
117
123
  raise e
118
124
  end
119
-
125
+
120
126
  if block_given?
121
127
  begin
122
128
  yield(self)
123
129
  ensure
124
130
  self.destroy
125
131
  end
126
-
132
+
127
133
  return self
128
134
  else
129
135
  return self
130
136
  end
131
137
  end
132
-
138
+
133
139
  #Starts listening on the given IO's. It is useally not needed to call this method manually.
134
140
  def listen
135
141
  #Start listening for input.
136
142
  start_listen
137
-
143
+
138
144
  #Start listening for errors.
139
145
  start_listen_errors
140
146
  end
141
-
147
+
142
148
  #First tries to make the sub-process exit gently. Then kills it with "TERM" and 9 afterwards to make sure its dead. If 'spawn_process' is given a block, this method is automatically ensured after the block is run.
143
149
  def destroy
144
150
  return nil if self.destroyed?
145
-
151
+
146
152
  debug "Destroying Ruby-process (#{caller}).\n" if @debug
147
153
  pid = @pid
148
154
  tries = 0
149
-
155
+
150
156
  #Make main kill it and make sure its dead...
151
157
  begin
152
- if @main and @pid
158
+ if @main && @pid
153
159
  tries += 1
154
160
  Process.kill("TERM", pid) rescue Errno::ESRCH
155
-
161
+
156
162
  #Ensure subprocess is dead.
157
163
  begin
158
164
  Timeout.timeout(1) do
159
165
  sleep 0.01
160
-
166
+
161
167
  loop do
162
168
  begin
163
169
  Process.getpgid(pid)
@@ -165,7 +171,7 @@ class Ruby_process
165
171
  rescue Errno::ESRCH
166
172
  alive = false
167
173
  end
168
-
174
+
169
175
  break if !alive
170
176
  end
171
177
  end
@@ -178,74 +184,74 @@ class Ruby_process
178
184
  #Process is already dead - ignore.
179
185
  ensure
180
186
  @pid = nil
181
-
187
+
182
188
  @io_out.close if @io_out && !@io_out.closed?
183
189
  @io_out = nil
184
-
190
+
185
191
  @io_in.close if @io_in && !@io_in.closed?
186
192
  @io_in = nil
187
-
193
+
188
194
  @io_err if @io_err && !@io_err.closed?
189
195
  @io_err = nil
190
-
196
+
191
197
  @main = nil
192
198
  end
193
-
199
+
194
200
  return nil
195
201
  end
196
-
202
+
197
203
  #Returns true if the Ruby process has been destroyed.
198
204
  def destroyed?
199
- return true if !@pid and !@io_out and !@io_in and !@io_err and @main == nil
205
+ return true if !@pid && !@io_out && !@io_in && !@io_err && @main == nil
200
206
  return false
201
207
  end
202
-
208
+
203
209
  #Joins the listen thread and error-thread. This is useually only called on the sub-process side, but can also be useful, if you are waiting for a delayed callback from the subprocess.
204
210
  def join
205
211
  debug "Joining listen-thread.\n" if @debug
206
212
  @thr_listen.join if @thr_listen
207
213
  raise @listen_err if @listen_err
208
-
214
+
209
215
  debug "Joining error-thread.\n" if @debug
210
216
  @thr_err.join if @thr_join
211
217
  raise @listen_err_err if @listen_err_err
212
218
  end
213
-
219
+
214
220
  #Sends a command to the other process. This should not be called manually, but is used by various other parts of the framework.
215
221
  def send(obj, &block)
216
222
  alive_check!
217
-
223
+
218
224
  #Sync ID stuff so they dont get mixed up.
219
225
  id = nil
220
226
  @send_mutex.synchronize do
221
227
  id = @send_count
222
228
  @send_count += 1
223
229
  end
224
-
230
+
225
231
  #Parse block.
226
232
  if block
227
- block_proxy_res = self.send(:cmd => :spawn_proxy_block, :id => block.__id__, :answer_id => id)
233
+ block_proxy_res = self.send(cmd: :spawn_proxy_block, id: block.__id__, answer_id: id)
228
234
  block_proxy_res_id = block_proxy_res[:id]
229
- raise "No block ID was returned?" if !block_proxy_res_id
235
+ raise "No block ID was returned?" unless block_proxy_res_id
230
236
  raise "Invalid block-ID: '#{block_proxy_res_id}'." if block_proxy_res_id.to_i <= 0
231
237
  @proxy_objs[block_proxy_res_id] = block
232
238
  @proxy_objs_ids[block.__id__] = block_proxy_res_id
233
239
  ObjectSpace.define_finalizer(block, self.method(:proxyobj_finalizer))
234
240
  obj[:block] = {
235
- :id => block_proxy_res_id,
236
- :arity => block.arity
241
+ id: block_proxy_res_id,
242
+ arity: block.arity
237
243
  }
238
244
  end
239
-
240
- flush_finalized if obj[:cmd] != :flush_finalized
241
-
245
+
246
+ flush_finalized unless obj[:cmd] == :flush_finalized
247
+
242
248
  debug "Sending(#{id}): #{obj}\n" if @debug
243
249
  line = Base64.strict_encode64(Marshal.dump(
244
- :id => id,
245
- :type => :send,
246
- :obj => obj
250
+ id: id,
251
+ type: :send,
252
+ obj: obj
247
253
  ))
248
-
254
+
249
255
  begin
250
256
  @answers[id] = Queue.new
251
257
  @io_out.puts(line)
@@ -255,7 +261,7 @@ class Ruby_process
255
261
  @answers.delete(id)
256
262
  end
257
263
  end
258
-
264
+
259
265
  #Returns true if the child process is still running. Otherwise false.
260
266
  def alive?
261
267
  begin
@@ -265,9 +271,9 @@ class Ruby_process
265
271
  return false
266
272
  end
267
273
  end
268
-
274
+
269
275
  private
270
-
276
+
271
277
  #Raises an error if the subprocess is no longer alive.
272
278
  def alive_check!
273
279
  raise "Has been destroyed." if self.destroyed?
@@ -276,14 +282,14 @@ class Ruby_process
276
282
  raise "'io_in' was closed." if @io_in.closed?
277
283
  raise "No listen thread." if !@thr_listen
278
284
  #raise "Listen thread wasnt alive?" if !@thr_listen.alive?
279
-
285
+
280
286
  return nil
281
287
  end
282
-
288
+
283
289
  #Prints the given string to stderr. Raises error if debugging is not enabled.
284
290
  def debug(str_full)
285
- raise "Debug not enabled?" if !@debug
286
-
291
+ raise "Debug not enabled?" unless @debug
292
+
287
293
  str_full.each_line do |str|
288
294
  if @main
289
295
  $stderr.print "(M#{@my_pid}) #{str}"
@@ -292,54 +298,54 @@ class Ruby_process
292
298
  end
293
299
  end
294
300
  end
295
-
301
+
296
302
  #Registers an object ID as a proxy-object on the host-side.
297
303
  def proxyobj_get(id, pid = @my_pid)
298
304
  if proxy_obj = @proxy_objs.get!(id)
299
305
  debug "Reuse proxy-obj (ID: #{id}, PID: #{pid}, fID: #{proxy_obj.args[:id]}, fPID: #{proxy_obj.args[:pid]})\n" if @debug
300
306
  return proxy_obj
301
307
  end
302
-
308
+
303
309
  @proxy_objs_unsets.delete(id)
304
- proxy_obj = Ruby_process::Proxyobj.new(self, id, pid)
310
+ proxy_obj = RubyProcess::ProxyObject.new(self, id, pid)
305
311
  @proxy_objs[id] = proxy_obj
306
312
  @proxy_objs_ids[proxy_obj.__id__] = id
307
313
  ObjectSpace.define_finalizer(proxy_obj, self.method(:proxyobj_finalizer))
308
-
314
+
309
315
  return proxy_obj
310
316
  end
311
-
317
+
312
318
  #Returns the saved proxy-object by the given ID. Raises error if it doesnt exist.
313
319
  def proxyobj_object(id)
314
320
  if obj = @objects[id]
315
321
  return obj
316
322
  end
317
-
323
+
318
324
  raise "No object by that ID: '#{id}' (#{@objects})."
319
325
  end
320
-
326
+
321
327
  #Method used for detecting garbage-collected proxy-objects. This way we can also free references to them in the other process, so it doesnt run out of memory.
322
328
  def proxyobj_finalizer(id)
323
329
  debug "Finalized #{id}\n" if @debug
324
330
  proxy_id = @proxy_objs_ids[id]
325
-
331
+
326
332
  if !proxy_id
327
333
  debug "No such ID in proxy objects IDs hash: '#{id}'.\n" if @debug
328
334
  else
329
335
  @proxy_objs_unsets << proxy_id
330
336
  debug "Done finalizing #{id}\n" if @debug
331
337
  end
332
-
338
+
333
339
  return nil
334
340
  end
335
-
341
+
336
342
  #Waits for an answer to appear in the answers-hash. Then deletes it from hash and returns it.
337
343
  def answer_read(id)
338
344
  loop do
339
345
  debug "Waiting for answer #{id}\n" if @debug
340
346
  answer = @answers[id].pop
341
347
  debug "Returning answer #{id}\n" if @debug
342
-
348
+
343
349
  if answer.is_a?(Hash) and type = answer[:type]
344
350
  if type == :error and class_str = answer[:class] and msg = answer[:msg] and bt_orig = answer[:bt]
345
351
  begin
@@ -349,17 +355,17 @@ class Ruby_process
349
355
  bt_orig.each do |btline|
350
356
  bt << "(#{@pid}): #{btline}"
351
357
  end
352
-
358
+
353
359
  bt += e.backtrace
354
360
  e.set_backtrace(bt)
355
361
  raise e
356
362
  end
357
- elsif type == :proxy_obj and id = answer[:id] and pid = answer[:pid]
363
+ elsif type == :proxy_obj && id = answer[:id] and pid = answer[:pid]
358
364
  return proxyobj_get(id, pid)
359
365
  elsif type == :proxy_block_call and block = answer[:block] and args = answer[:args] and queue = answer[:queue]
360
366
  #Calls the block. This is used to call the block from the same thread that the answer is being read from. This can cause problems in Hayabusa, that uses thread-variables to determine output and such.
361
367
  block.call(*args)
362
-
368
+
363
369
  #Tells the parent thread that the block has been executed and it should continue.
364
370
  queue << true
365
371
  else
@@ -369,19 +375,19 @@ class Ruby_process
369
375
  return answer
370
376
  end
371
377
  end
372
-
378
+
373
379
  raise "This should never be reached."
374
380
  end
375
-
381
+
376
382
  #Starts the listen-thread that listens for, and executes, commands. This is normally automatically called and should not be called manually.
377
383
  def start_listen
378
384
  @thr_listen = Thread.new do
379
385
  begin
380
386
  @io_in.each_line do |line|
381
- raise "No line?" if !line or line.to_s.strip.empty?
387
+ raise "No line?" if !line || line.to_s.strip.empty?
382
388
  alive_check!
383
389
  debug "Received: #{line}" if @debug
384
-
390
+
385
391
  begin
386
392
  obj = Marshal.load(Base64.strict_decode64(line.strip))
387
393
  debug "Object received: #{obj}\n" if @debug
@@ -389,28 +395,28 @@ class Ruby_process
389
395
  $stderr.puts "Base64Str: #{line}" if @debug
390
396
  $stderr.puts e.inspect if @debug
391
397
  $stderr.puts e.backtrace if @debug
392
-
398
+
393
399
  raise e
394
400
  end
395
-
401
+
396
402
  id = obj[:id]
397
403
  obj_type = obj[:type]
398
-
404
+
399
405
  if obj_type == :send
400
406
  Thread.new do
401
407
  #Hack to be able to do callbacks from same thread when using blocks. This should properly be cleaned a bit up in the future.
402
408
  obj[:obj][:send_id] = id
403
-
409
+
404
410
  begin
405
- raise "Object was not a hash." if !obj.is_a?(Hash)
406
- raise "No ID was given?" if !id
411
+ raise "Object was not a hash." unless obj.is_a?(Hash)
412
+ raise "No ID was given?" unless id
407
413
  res = self.__send__("cmd_#{obj[:obj][:cmd]}", obj[:obj])
408
414
  rescue Exception => e
409
- raise e if e.is_a?(SystemExit) or e.is_a?(Interrupt)
410
- res = {:type => :error, :class => e.class.name, :msg => e.message, :bt => e.backtrace}
415
+ raise e if e.is_a?(SystemExit) || e.is_a?(Interrupt)
416
+ res = {type: :error, class: e.class.name, msg: e.message, bt: e.backtrace}
411
417
  end
412
-
413
- data = Base64.strict_encode64(Marshal.dump(:type => :answer, :id => id, :answer => res))
418
+
419
+ data = Base64.strict_encode64(Marshal.dump(type: :answer, id: id, answer: res))
414
420
  @io_out.puts(data)
415
421
  end
416
422
  elsif obj_type == :answer
@@ -429,16 +435,16 @@ class Ruby_process
429
435
  debug "Error while listening: #{e.inspect}"
430
436
  debug e.backtrace.join("\n") + "\n"
431
437
  end
432
-
438
+
433
439
  @listen_err = e
434
440
  end
435
441
  end
436
442
  end
437
-
443
+
438
444
  #Starts the listen thread that outputs the 'stderr' for the other process on this process's 'stderr'.
439
445
  def start_listen_errors
440
446
  return nil if !@io_err
441
-
447
+
442
448
  @thr_err = Thread.new do
443
449
  begin
444
450
  @io_err.each_line do |str|
@@ -449,4 +455,4 @@ class Ruby_process
449
455
  end
450
456
  end
451
457
  end
452
- end
458
+ end