ruby_process 0.0.5 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.5
1
+ 0.0.7
@@ -74,11 +74,16 @@ class Ruby_process
74
74
  if args and args[:exec]
75
75
  cmd = "#{args[:exec]}"
76
76
  else
77
- cmd = "ruby"
77
+ if !ENV["rvm_ruby_string"].to_s.empty?
78
+ cmd = "#{ENV["rvm_ruby_string"]}"
79
+ else
80
+ cmd = "ruby"
81
+ end
78
82
  end
79
83
 
80
84
  cmd << " \"#{File.realpath(File.dirname(__FILE__))}/../scripts/ruby_process_script.rb\" --pid=#{@my_pid}"
81
85
  cmd << " --debug" if @args[:debug]
86
+ cmd << " \"--title=#{@args[:title]}\"" if !@args[:title].to_s.strip.empty?
82
87
 
83
88
  #Start process and set IO variables.
84
89
  require "open3"
@@ -117,7 +122,7 @@ class Ruby_process
117
122
  self.destroy
118
123
  end
119
124
 
120
- return nil
125
+ return self
121
126
  else
122
127
  return self
123
128
  end
@@ -164,7 +169,7 @@ class Ruby_process
164
169
 
165
170
  #Sends a command to the other process. This should not be called manually, but is used by various other parts of the framework.
166
171
  def send(obj, &block)
167
- raise "Ruby-process is dead." if !alive?
172
+ alive_check!
168
173
 
169
174
  #Parse block.
170
175
  if block
@@ -196,11 +201,22 @@ class Ruby_process
196
201
  :type => :send,
197
202
  :obj => obj
198
203
  ))
204
+ @answers[id] = Queue.new
199
205
  @io_out.puts(line)
200
- sleep 0.001
206
+
201
207
  return answer_read(id)
202
208
  end
203
209
 
210
+ #Returns true if the child process is still running. Otherwise false.
211
+ def alive?
212
+ begin
213
+ self.alive_check!
214
+ return true
215
+ rescue
216
+ return false
217
+ end
218
+ end
219
+
204
220
  private
205
221
 
206
222
  def debug(str_full)
@@ -215,15 +231,14 @@ class Ruby_process
215
231
  end
216
232
  end
217
233
 
218
- #Returns true if the child process is still running. Otherwise false.
219
- def alive?
220
- return false if !@io_out or !@io_in or @io_in.closed?
221
- return true
222
- end
223
-
224
234
  #Raises an error if the subprocess is no longer alive.
225
235
  def alive_check!
226
- raise "Process is dead." unless alive?
236
+ raise "No 'io_out'." if !@io_out
237
+ raise "No 'io_in'." if !@io_in
238
+ raise "'io_in' was closed." if @io_in.closed?
239
+ raise "No listen thread." if !@thr_listen
240
+ raise "Listen thread wasnt alive?" if !@thr_listen.alive?
241
+
227
242
  return nil
228
243
  end
229
244
 
@@ -267,39 +282,29 @@ class Ruby_process
267
282
  #Waits for an answer to appear in the answers-hash. Then deletes it from hash and returns it.
268
283
  def answer_read(id)
269
284
  debug "Waiting for answer #{id}\n" if @debug
285
+ answer = @answers[id].pop
270
286
 
271
- loop do
272
- if @answers.key?(id)
273
- debug "Returning answer #{id}\n" if @debug
274
- answer = @answers[id]
275
- @answers.delete(id)
276
-
277
- if answer.is_a?(Hash) and answer[:type] == :error and answer.key?(:class) and answer.key?(:msg) and answer.key?(:bt)
278
- begin
279
- raise "#{answer[:class]}: #{answer[:msg]}"
280
- rescue => e
281
- bt = []
282
- answer[:bt].each do |btline|
283
- bt << "(#{@pid}): #{btline}"
284
- end
285
-
286
- bt += e.backtrace
287
- e.set_backtrace(bt)
288
- raise e
289
- end
290
- elsif answer.is_a?(Hash) and answer[:type] == :proxy_obj and answer.key?(:id)
291
- return proxyobj_get(answer[:id], answer[:pid])
287
+ debug "Returning answer #{id}\n" if @debug
288
+ @answers.delete(id)
289
+
290
+ if answer.is_a?(Hash) and answer[:type] == :error and answer.key?(:class) and answer.key?(:msg) and answer.key?(:bt)
291
+ begin
292
+ raise "#{answer[:class]}: #{answer[:msg]}"
293
+ rescue => e
294
+ bt = []
295
+ answer[:bt].each do |btline|
296
+ bt << "(#{@pid}): #{btline}"
292
297
  end
293
298
 
294
- return answer
299
+ bt += e.backtrace
300
+ e.set_backtrace(bt)
301
+ raise e
295
302
  end
296
-
297
- debug "No answer by ID #{id} - sleeping...\n" if @debug
298
- sleep 0.01
299
- alive_check!
300
- raise @listen_err if @listen_err
301
- raise "Not listening." if !@thr_listen or !@thr_listen.alive?
303
+ elsif answer.is_a?(Hash) and answer[:type] == :proxy_obj and answer.key?(:id)
304
+ return proxyobj_get(answer[:id], answer[:pid])
302
305
  end
306
+
307
+ return answer
303
308
  end
304
309
 
305
310
  #Starts the listen-thread that listens for, and executes, commands.
@@ -336,9 +341,9 @@ class Ruby_process
336
341
  data = Base64.strict_encode64(Marshal.dump(:type => :answer, :id => obj[:id], :answer => res))
337
342
  @io_out.puts(data)
338
343
  end
339
- elsif obj[:type] == :answer
340
- debug "Answer #{obj[:id]} saved.\n" if @debug
341
- @answers[obj[:id]] = obj[:answer]
344
+ elsif obj[:type] == :answer and id = obj[:id].to_i
345
+ debug "Answer #{id} saved.\n" if @debug
346
+ @answers[id] << obj[:answer]
342
347
  else
343
348
  raise "Unknown object: '#{obj}'."
344
349
  end
@@ -363,39 +368,4 @@ class Ruby_process
363
368
  end
364
369
  end
365
370
  end
366
- end
367
-
368
- #This class handels the calling of methods on objects in the other process seamlessly.
369
- class Ruby_process::Proxyobj
370
- #Hash that contains various information about the proxyobj.
371
- attr_reader :args
372
-
373
- #Constructor. This should not be called manually but through a running 'Ruby_process'.
374
- #===Examples
375
- # proxy_obj = rp.new(:String, "Kasper") #=> <Ruby_process::Proxyobj>
376
- # proxy_obj = rp.static(:File, :open, "/tmp/somefile") #=> <Ruby_process::Proxyobj>
377
- def initialize(args)
378
- @args = args
379
- end
380
-
381
- #Returns the object as the real object transfered by using the marshal-lib.
382
- #===Examples
383
- # str = rp.new(:String, "Kasper") #=> <Ruby_process::Proxyobj>
384
- # str.__rp_marshal #=> "Kasper"
385
- def __rp_marshal
386
- return Marshal.load(@args[:rp].send(:cmd => :obj_marshal, :id => @args[:id]))
387
- end
388
-
389
- #Proxies all calls to the process-object.
390
- #===Examples
391
- # str = rp.new(:String, "Kasper") #=> <Ruby_process::Proxyobj::1>
392
- # length_int = str.length #=> <Ruby_process::Proxyobj::2>
393
- # length_int.__rp_marshal #=> 6
394
- def method_missing(method, *args, &block)
395
- debug "Method-missing-args-before: #{args} (#{@my_pid})\n" if @debug
396
- real_args = @args[:rp].parse_args(args)
397
- debug "Method-missing-args-after: #{real_args}\n" if @debug
398
-
399
- return @args[:rp].send(:cmd => :obj_method, :id => @args[:id], :method => method, :args => real_args, &block)
400
- end
401
371
  end
@@ -27,8 +27,15 @@ class Ruby_process::Cproxy
27
27
  @@lock.synchronize do
28
28
  @@instances += 1
29
29
 
30
+ #Check if the sub-process is alive.
31
+ if @@subproc and !@@subproc.alive?
32
+ @@subproc.destroy
33
+ @@subproc = nil
34
+ end
35
+
36
+ #Start a new subprocess if none is defined and active.
30
37
  if !@@subproc
31
- @@subproc = Ruby_process.new
38
+ @@subproc = Ruby_process.new(:title => "cproxy", :debug => false)
32
39
  @@subproc.spawn_process
33
40
  end
34
41
  end
@@ -0,0 +1,50 @@
1
+ #This class handels the calling of methods on objects in the other process seamlessly.
2
+ class Ruby_process::Proxyobj
3
+ #Hash that contains various information about the proxyobj.
4
+ attr_reader :args
5
+
6
+ #Constructor. This should not be called manually but through a running 'Ruby_process'.
7
+ #===Examples
8
+ # proxy_obj = rp.new(:String, "Kasper") #=> <Ruby_process::Proxyobj>
9
+ # proxy_obj = rp.static(:File, :open, "/tmp/somefile") #=> <Ruby_process::Proxyobj>
10
+ def initialize(args)
11
+ @args = args
12
+ end
13
+
14
+ #Returns the object as the real object transfered by using the marshal-lib.
15
+ #===Examples
16
+ # str = rp.new(:String, "Kasper") #=> <Ruby_process::Proxyobj>
17
+ # str.__rp_marshal #=> "Kasper"
18
+ def __rp_marshal
19
+ return Marshal.load(@args[:rp].send(:cmd => :obj_marshal, :id => @args[:id]))
20
+ end
21
+
22
+ #Overwrite certain convert methods.
23
+ RUBY_METHODS = [:to_i, :to_s, :to_str, :to_f]
24
+ RUBY_METHODS.each do |method_name|
25
+ define_method(method_name) do |*args, &blk|
26
+ return @args[:rp].send(:cmd => :obj_method, :id => @args[:id], :method => method_name, :args => args, &blk).__rp_marshal
27
+ end
28
+ end
29
+
30
+ #Overwrite certain methods.
31
+ PROXY_METHODS = [:send]
32
+ PROXY_METHODS.each do |method_name|
33
+ define_method(method_name) do |*args, &blk|
34
+ self.method_missing(method_name, *args, &blk)
35
+ end
36
+ end
37
+
38
+ #Proxies all calls to the process-object.
39
+ #===Examples
40
+ # str = rp.new(:String, "Kasper") #=> <Ruby_process::Proxyobj::1>
41
+ # length_int = str.length #=> <Ruby_process::Proxyobj::2>
42
+ # length_int.__rp_marshal #=> 6
43
+ def method_missing(method, *args, &block)
44
+ debug "Method-missing-args-before: #{args} (#{@my_pid})\n" if @debug
45
+ real_args = @args[:rp].parse_args(args)
46
+ debug "Method-missing-args-after: #{real_args}\n" if @debug
47
+
48
+ return @args[:rp].send(:cmd => :obj_method, :id => @args[:id], :method => method, :args => real_args, &block)
49
+ end
50
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ruby_process}
8
- s.version = "0.0.5"
8
+ s.version = "0.0.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kasper Johansen"]
12
- s.date = %q{2012-10-14}
12
+ s.date = %q{2012-10-16}
13
13
  s.description = %q{A framework for spawning and communicating with other Ruby-processes}
14
14
  s.email = %q{k@spernj.org}
15
15
  s.extra_rdoc_files = [
@@ -37,9 +37,11 @@ Gem::Specification.new do |s|
37
37
  "include/args_handeling.rb",
38
38
  "lib/ruby_process.rb",
39
39
  "lib/ruby_process_cproxy.rb",
40
+ "lib/ruby_process_proxyobj.rb",
40
41
  "ruby_process.gemspec",
41
42
  "scripts/ruby_process_script.rb",
42
43
  "spec/cproxy_spec.rb",
44
+ "spec/hard_load_spec.rb",
43
45
  "spec/ruby_process_spec.rb",
44
46
  "spec/spec_helper.rb"
45
47
  ]
@@ -13,8 +13,10 @@ pid = nil
13
13
  ARGV.each do |arg|
14
14
  if arg == "--debug"
15
15
  debug = true
16
- elsif match = arg.match(/--pid=(\d+)/)
16
+ elsif match = arg.match(/--pid=(\d+)$/)
17
17
  pid = match[1].to_i
18
+ elsif match = arg.match(/--title=(.+)$/)
19
+ #ignore - its for finding process via 'ps aux'.
18
20
  else
19
21
  raise "Unknown argument: '#{arg}'."
20
22
  end
@@ -0,0 +1,39 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "RubyProcess" do
4
+ it "should be able to do basic stuff" do
5
+ Ruby_process::Cproxy.run do |data|
6
+ sp = data[:subproc]
7
+ sp.new(:String, "Wee")
8
+
9
+ ts = []
10
+
11
+ 1.upto(50) do |tcount|
12
+ ts << Thread.new do
13
+ 1.upto(250) do
14
+ str = sp.new(:String, "Kasper Johansen")
15
+
16
+ res1 = str.include?("Kasper")
17
+ str << " More"
18
+
19
+ res2 = str.include?("Johansen")
20
+ str << " Even more"
21
+
22
+ res3 = str.include?("Christina")
23
+ str << " Much more"
24
+
25
+ raise "Expected res1 to be true but it wasnt: '#{res1}'." if res1 != true
26
+ raise "Expected res2 to be true but it wasnt: '#{res2}'." if res2 != true
27
+ raise "Expected res3 to be false but it wasnt: '#{res3}'." if res3 != false
28
+
29
+ print "."
30
+ end
31
+ end
32
+ end
33
+
34
+ ts.each do |t|
35
+ t.join
36
+ end
37
+ end
38
+ end
39
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_process
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-14 00:00:00.000000000 +02:00
12
+ date: 2012-10-16 00:00:00.000000000 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: wref
17
- requirement: &12566380 !ruby/object:Gem::Requirement
17
+ requirement: &19833520 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *12566380
25
+ version_requirements: *19833520
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: tsafe
28
- requirement: &12565660 !ruby/object:Gem::Requirement
28
+ requirement: &19832660 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *12565660
36
+ version_requirements: *19832660
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: rspec
39
- requirement: &12564900 !ruby/object:Gem::Requirement
39
+ requirement: &19831800 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: 2.8.0
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *12564900
47
+ version_requirements: *19831800
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: rdoc
50
- requirement: &12564260 !ruby/object:Gem::Requirement
50
+ requirement: &19830660 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ~>
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: '3.12'
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *12564260
58
+ version_requirements: *19830660
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: bundler
61
- requirement: &12563400 !ruby/object:Gem::Requirement
61
+ requirement: &19828180 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: 1.0.0
67
67
  type: :development
68
68
  prerelease: false
69
- version_requirements: *12563400
69
+ version_requirements: *19828180
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: jeweler
72
- requirement: &12562600 !ruby/object:Gem::Requirement
72
+ requirement: &19827260 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ~>
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: 1.8.3
78
78
  type: :development
79
79
  prerelease: false
80
- version_requirements: *12562600
80
+ version_requirements: *19827260
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: rcov
83
- requirement: &12561560 !ruby/object:Gem::Requirement
83
+ requirement: &19826400 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ! '>='
@@ -88,7 +88,7 @@ dependencies:
88
88
  version: '0'
89
89
  type: :development
90
90
  prerelease: false
91
- version_requirements: *12561560
91
+ version_requirements: *19826400
92
92
  description: A framework for spawning and communicating with other Ruby-processes
93
93
  email: k@spernj.org
94
94
  executables: []
@@ -117,9 +117,11 @@ files:
117
117
  - include/args_handeling.rb
118
118
  - lib/ruby_process.rb
119
119
  - lib/ruby_process_cproxy.rb
120
+ - lib/ruby_process_proxyobj.rb
120
121
  - ruby_process.gemspec
121
122
  - scripts/ruby_process_script.rb
122
123
  - spec/cproxy_spec.rb
124
+ - spec/hard_load_spec.rb
123
125
  - spec/ruby_process_spec.rb
124
126
  - spec/spec_helper.rb
125
127
  has_rdoc: true
@@ -138,7 +140,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
138
140
  version: '0'
139
141
  segments:
140
142
  - 0
141
- hash: 4244816793884101144
143
+ hash: 1714435591026867569
142
144
  required_rubygems_version: !ruby/object:Gem::Requirement
143
145
  none: false
144
146
  requirements: