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,52 +1,52 @@
1
- #This class is used to seamlessly use leaky classes without working through 'Ruby_process'.
1
+ #This class is used to seamlessly use leaky classes without working through 'RubyProcess'.
2
2
  #===Examples
3
- # Ruby_process::Cproxy.run do |data|
3
+ # RubyProcess::ClassProxy.run do |data|
4
4
  # data[:subproc].static(:Object, :require, "rubygems")
5
5
  # data[:subproc].static(:Object, :require, "rexml/document")
6
- #
7
- # doc = Ruby_process::Cproxy::REXML::Document.new("test")
6
+ #
7
+ # doc = RubyProcess::ClassProxy::REXML::Document.new("test")
8
8
  # strio = StringIO.new
9
9
  # doc.write(strio)
10
10
  # puts strio.string #=> "<test/>"
11
11
  # raise "REXML shouldnt be defined?" if Kernel.const_defined?(:REXML)
12
- class Ruby_process::Cproxy
12
+ class RubyProcess::ClassProxy
13
13
  #Lock is used to to create new Ruby-process-instances and not doing double-counts.
14
14
  @@lock = Mutex.new
15
-
15
+
16
16
  #Counts how many instances are using the Cproxy-module. This way it can be safely unset once no-body is using it again.
17
17
  @@instances = 0
18
-
19
- #This variable will hold the 'Ruby_process'-object where sub-objects will be created.
18
+
19
+ #This variable will hold the 'RubyProcess'-object where sub-objects will be created.
20
20
  @@subproc = nil
21
-
21
+
22
22
  #All use should go through this method to automatically destroy sub-processes and keep track of ressources.
23
23
  def self.run
24
24
  #Increase count of instances that are using Cproxy and set the subproc-object if not already set.
25
25
  @@lock.synchronize do
26
26
  #Check if the sub-process is alive.
27
- if @@subproc and (!@@subproc.alive? or @@subproc.destroyed?)
27
+ if @@subproc && (!@@subproc.alive? || @@subproc.destroyed?)
28
28
  raise "Cant destroy sub-process because instances are running: '#{@@instances}'." if @@instances > 0
29
29
  @@subproc.destroy
30
30
  @@subproc = nil
31
31
  end
32
-
32
+
33
33
  #Start a new subprocess if none is defined and active.
34
- if !@@subproc
35
- subproc = Ruby_process.new(:title => "ruby_process_cproxy", :debug => false)
34
+ unless @@subproc
35
+ subproc = RubyProcess.new(title: "ruby_process_cproxy", debug: false)
36
36
  subproc.spawn_process
37
37
  @@subproc = subproc
38
38
  end
39
-
39
+
40
40
  @@instances += 1
41
41
  end
42
-
42
+
43
43
  begin
44
- yield(:subproc => @@subproc)
44
+ yield(subproc: @@subproc)
45
45
  raise "'run'-caller destroyed sub-process. This shouldn't happen." if @@subproc.destroyed?
46
46
  ensure
47
47
  @@lock.synchronize do
48
48
  @@instances -= 1
49
-
49
+
50
50
  if @@instances <= 0
51
51
  begin
52
52
  @@subproc.destroy
@@ -58,49 +58,49 @@ class Ruby_process::Cproxy
58
58
  end
59
59
  end
60
60
  end
61
-
62
- #Returns the 'Ruby_process'-object or raises an error if it has not been set.
61
+
62
+ #Returns the 'RubyProcess'-object or raises an error if it has not been set.
63
63
  def self.subproc
64
- raise "CProxy process not set for some reason?" if !@@subproc
64
+ raise "CProxy process not set for some reason?" unless @@subproc
65
65
  return @@subproc
66
66
  end
67
-
67
+
68
68
  #Destroy all loaded sub-process-constants.
69
69
  def self.destroy_loaded_constants
70
70
  self.constants.each do |constant|
71
71
  self.__send__(:remove_const, constant)
72
72
  end
73
73
  end
74
-
75
- #Creates the new constant under the 'Ruby_process::Cproxy'-namespace.
74
+
75
+ #Creates the new constant under the 'RubyProcess::ClassProxy'-namespace.
76
76
  def self.const_missing(name)
77
- Ruby_process::Cproxy.load_class(self, name) if !self.const_defined?(name)
78
- raise "Still not created on const: '#{name}'." if !self.const_defined?(name)
77
+ RubyProcess::ClassProxy.load_class(self, name) unless const_defined?(name)
78
+ raise "Still not created on const: '#{name}'." unless const_defined?(name)
79
79
  return self.const_get(name)
80
80
  end
81
-
81
+
82
82
  #Loads a new class to the given constants namespace for recursive creating of missing classes.
83
83
  def self.load_class(const, name)
84
84
  const.const_set(name, Class.new{
85
85
  #Use 'const_missing' to auto-create missing sub-constants recursivly.
86
86
  def self.const_missing(name)
87
- Ruby_process::Cproxy.load_class(self, name) if !self.const_defined?(name)
88
- raise "Still not created on const: '#{name}'." if !self.const_defined?(name)
87
+ RubyProcess::ClassProxy.load_class(self, name) unless const_defined?(name)
88
+ raise "Still not created on const: '#{name}'." unless self.const_defined?(name)
89
89
  return self.const_get(name)
90
90
  end
91
-
91
+
92
92
  #Manipulate 'new'-method return proxy-objects instead of real objects.
93
93
  def self.new(*args, &blk)
94
- name_match = self.name.to_s.match(/^Ruby_process::Cproxy::(.+)$/)
94
+ name_match = self.name.to_s.match(/^RubyProcess::ClassProxy::(.+)$/)
95
95
  class_name = name_match[1]
96
- return Ruby_process::Cproxy.subproc.new(class_name, *args, &blk)
96
+ return RubyProcess::ClassProxy.subproc.new(class_name, *args, &blk)
97
97
  end
98
-
98
+
99
99
  def self.method_missing(method_name, *args, &blk)
100
- name_match = self.name.to_s.match(/^Ruby_process::Cproxy::(.+)$/)
100
+ name_match = self.name.to_s.match(/^RubyProcess::ClassProxy::(.+)$/)
101
101
  class_name = name_match[1]
102
- return Ruby_process::Cproxy.subproc.static(class_name, method_name, *args, &blk)
102
+ return RubyProcess::ClassProxy.subproc.static(class_name, method_name, *args, &blk)
103
103
  end
104
104
  })
105
105
  end
106
- end
106
+ end
@@ -1,37 +1,37 @@
1
1
  #This class handels the calling of methods on objects in the other process seamlessly.
2
- class Ruby_process::Proxyobj
2
+ class RubyProcess::ProxyObject
3
3
  #Hash that contains various information about the proxyobj.
4
4
  attr_reader :__rp_rp, :__rp_id, :__rp_pid
5
-
6
- #Constructor. This should not be called manually but through a running 'Ruby_process'.
5
+
6
+ #Constructor. This should not be called manually but through a running 'RubyProcess'.
7
7
  #===Examples
8
- # proxy_obj = rp.new(:String, "Kasper") #=> <Ruby_process::Proxyobj>
9
- # proxy_obj = rp.static(:File, :open, "/tmp/somefile") #=> <Ruby_process::Proxyobj>
8
+ # proxy_obj = rp.new(:String, "Kasper") #=> <RubyProcess::ProxyObject>
9
+ # proxy_obj = rp.static(:File, :open, "/tmp/somefile") #=> <RubyProcess::ProxyObject>
10
10
  def initialize(rp, id, pid)
11
11
  @__rp_rp, @__rp_id, @__rp_pid = rp, id, pid
12
12
  end
13
-
13
+
14
14
  #Returns the object as the real object transfered by using the marshal-lib.
15
15
  #===Examples
16
- # str = rp.new(:String, "Kasper") #=> <Ruby_process::Proxyobj>
16
+ # str = rp.new(:String, "Kasper") #=> <RubyProcess::ProxyObject>
17
17
  # str.__rp_marshal #=> "Kasper"
18
18
  def __rp_marshal
19
- return Marshal.load(@__rp_rp.send(:cmd => :obj_marshal, :id => @__rp_id))
19
+ return Marshal.load(@__rp_rp.send(cmd: :obj_marshal, id: @__rp_id))
20
20
  end
21
-
21
+
22
22
  #Unsets all data on the object.
23
23
  def __rp_destroy
24
24
  @__rp_id = nil, @__rp_rp = nil, @__rp_pid = nil
25
25
  end
26
-
26
+
27
27
  #Overwrite certain convert methods.
28
28
  RUBY_METHODS = [:to_i, :to_s, :to_str, :to_f]
29
29
  RUBY_METHODS.each do |method_name|
30
30
  define_method(method_name) do |*args, &blk|
31
- return @__rp_rp.send(:cmd => :obj_method, :id => @__rp_id, :method => method_name, :args => args, &blk).__rp_marshal
31
+ return @__rp_rp.send(cmd: :obj_method, id: @__rp_id, method: method_name, args: args, &blk).__rp_marshal
32
32
  end
33
33
  end
34
-
34
+
35
35
  #Overwrite certain methods.
36
36
  PROXY_METHODS = [:send]
37
37
  PROXY_METHODS.each do |method_name|
@@ -39,17 +39,17 @@ class Ruby_process::Proxyobj
39
39
  self.method_missing(method_name, *args, &blk)
40
40
  end
41
41
  end
42
-
42
+
43
43
  #Proxies all calls to the process-object.
44
44
  #===Examples
45
- # str = rp.new(:String, "Kasper") #=> <Ruby_process::Proxyobj::1>
46
- # length_int = str.length #=> <Ruby_process::Proxyobj::2>
45
+ # str = rp.new(:String, "Kasper") #=> <RubyProcess::ProxyObject::1>
46
+ # length_int = str.length #=> <RubyProcess::ProxyObject::2>
47
47
  # length_int.__rp_marshal #=> 6
48
48
  def method_missing(method, *args, &block)
49
49
  debug "Method-missing-args-before: #{args} (#{@__rp_pid})\n" if @debug
50
50
  real_args = @__rp_rp.parse_args(args)
51
51
  debug "Method-missing-args-after: #{real_args}\n" if @debug
52
-
53
- return @__rp_rp.send(:cmd => :obj_method, :id => @__rp_id, :method => method, :args => real_args, &block)
52
+
53
+ return @__rp_rp.send(cmd: :obj_method, id: @__rp_id, method: method, args: real_args, &block)
54
54
  end
55
- end
55
+ end
@@ -2,27 +2,30 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
+ # stub: ruby_process 0.0.13 ruby lib
5
6
 
6
7
  Gem::Specification.new do |s|
7
8
  s.name = "ruby_process"
8
- s.version = "0.0.9"
9
+ s.version = "0.0.13"
9
10
 
10
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
11
13
  s.authors = ["Kasper Johansen"]
12
- s.date = "2013-12-10"
14
+ s.date = "2015-04-06"
13
15
  s.description = "A framework for spawning and communicating with other Ruby-processes"
14
16
  s.email = "k@spernj.org"
15
17
  s.extra_rdoc_files = [
16
18
  "LICENSE.txt",
17
- "README.rdoc"
19
+ "README.md"
18
20
  ]
19
21
  s.files = [
20
22
  ".document",
21
23
  ".rspec",
22
24
  "Gemfile",
23
25
  "LICENSE.txt",
24
- "README.rdoc",
26
+ "README.md",
25
27
  "Rakefile",
28
+ "RubyProcess.gemspec",
26
29
  "VERSION",
27
30
  "cmds/blocks.rb",
28
31
  "cmds/marshal.rb",
@@ -31,16 +34,18 @@ Gem::Specification.new do |s|
31
34
  "cmds/static.rb",
32
35
  "cmds/str_eval.rb",
33
36
  "cmds/system.rb",
37
+ "examples/example_csv.rb",
34
38
  "examples/example_file_write.rb",
35
39
  "examples/example_knj_db_dump.rb",
36
40
  "examples/example_strscan.rb",
37
41
  "include/args_handeling.rb",
38
42
  "lib/ruby_process.rb",
39
- "lib/ruby_process_cproxy.rb",
40
- "lib/ruby_process_proxyobj.rb",
43
+ "lib/ruby_process/class_proxy.rb",
44
+ "lib/ruby_process/proxy_object.rb",
41
45
  "ruby_process.gemspec",
42
46
  "scripts/ruby_process_script.rb",
43
- "spec/cproxy_spec.rb",
47
+ "shippable.yml",
48
+ "spec/class_proxy_spec.rb",
44
49
  "spec/hard_load_spec.rb",
45
50
  "spec/leaks_spec.rb",
46
51
  "spec/ruby_process_spec.rb",
@@ -48,16 +53,16 @@ Gem::Specification.new do |s|
48
53
  ]
49
54
  s.homepage = "http://github.com/kaspernj/ruby_process"
50
55
  s.licenses = ["MIT"]
51
- s.require_paths = ["lib"]
52
- s.rubygems_version = "1.8.23"
56
+ s.rubygems_version = "2.4.0"
53
57
  s.summary = "A framework for spawning and communicating with other Ruby-processes"
54
58
 
55
59
  if s.respond_to? :specification_version then
56
- s.specification_version = 3
60
+ s.specification_version = 4
57
61
 
58
62
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
59
63
  s.add_runtime_dependency(%q<wref>, [">= 0"])
60
64
  s.add_runtime_dependency(%q<tsafe>, [">= 0"])
65
+ s.add_runtime_dependency(%q<string-cases>, [">= 0"])
61
66
  s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
62
67
  s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
63
68
  s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
@@ -65,6 +70,7 @@ Gem::Specification.new do |s|
65
70
  else
66
71
  s.add_dependency(%q<wref>, [">= 0"])
67
72
  s.add_dependency(%q<tsafe>, [">= 0"])
73
+ s.add_dependency(%q<string-cases>, [">= 0"])
68
74
  s.add_dependency(%q<rspec>, ["~> 2.8.0"])
69
75
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
70
76
  s.add_dependency(%q<bundler>, [">= 1.0.0"])
@@ -73,6 +79,7 @@ Gem::Specification.new do |s|
73
79
  else
74
80
  s.add_dependency(%q<wref>, [">= 0"])
75
81
  s.add_dependency(%q<tsafe>, [">= 0"])
82
+ s.add_dependency(%q<string-cases>, [">= 0"])
76
83
  s.add_dependency(%q<rspec>, ["~> 2.8.0"])
77
84
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
78
85
  s.add_dependency(%q<bundler>, [">= 1.0.0"])
@@ -25,13 +25,13 @@ end
25
25
  debug = true if ARGV.index("--debug") != nil
26
26
  raise "No PID given of parent process." if !pid
27
27
 
28
- rps = Ruby_process.new(
29
- :in => $stdin,
30
- :out => $stdout,
31
- :err => $stderr,
32
- :debug => debug,
33
- :pid => pid
28
+ rps = RubyProcess.new(
29
+ in: $stdin,
30
+ out: $stdout,
31
+ err: $stderr,
32
+ debug: debug,
33
+ pid: pid
34
34
  )
35
35
  rps.listen
36
36
  $stdout.puts("ruby_process_started")
37
- rps.join
37
+ rps.join
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
4
+ script:
5
+ - CODECLIMATE_REPO_TOKEN=32061319cc6d2e0bd0d0eb88afdc6d7b68829b357ca76efb99f86d7a1a89539e bundle exec rspec
6
+ notifications:
7
+ email: false
@@ -0,0 +1,95 @@
1
+ require "spec_helper"
2
+
3
+ describe "RubyProcess" do
4
+ it "should be able to do quick in-and-outs without leaking" do
5
+ ts = []
6
+
7
+ 1.upto(2) do |tcount|
8
+ ts << Thread.new do
9
+ 1.upto(10) do
10
+ RubyProcess::ClassProxy.run do |data|
11
+ sp = data[:subproc]
12
+ str = sp.new(:String, "Wee")
13
+ str.__rp_marshal.should eq "Wee"
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ ts.each do |thread|
20
+ thread.join
21
+ end
22
+ end
23
+
24
+ it "should be able to do basic stuff" do
25
+ require "stringio"
26
+
27
+ RubyProcess::ClassProxy.run do |data|
28
+ data[:subproc].static(:Object, :require, "rubygems")
29
+ data[:subproc].static(:Object, :require, "rexml/document")
30
+
31
+ doc = RubyProcess::ClassProxy::REXML::Document.new
32
+ doc.add_element("test")
33
+
34
+ strio = StringIO.new
35
+ doc.write(strio)
36
+
37
+ Kernel.const_defined?(:REXML).should eq false
38
+ strio.string.should eq "<test/>"
39
+ end
40
+ end
41
+
42
+ it "should be able to do multiple calls at once" do
43
+ ts = []
44
+
45
+ 0.upto(9) do |tcount|
46
+ ts << Thread.new do
47
+ RubyProcess::ClassProxy.run do |data|
48
+ sp = data[:subproc]
49
+ sp.new(:String, "Wee")
50
+
51
+ 1.upto(250) do
52
+ str = sp.new(:String, "Kasper Johansen")
53
+
54
+ str.__rp_marshal.should include "Kasper"
55
+ str << " More"
56
+
57
+ str.__rp_marshal.should include "Johansen"
58
+ str << " Even more"
59
+
60
+ str.__rp_marshal.should_not include "Christina"
61
+ str << " Much more"
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ count = 0
68
+ ts.each do |t|
69
+ count += 1
70
+ #puts "Thread #{count}"
71
+ t.join
72
+ end
73
+ end
74
+
75
+ it "should not leak" do
76
+ str = "kasper"
77
+ str = nil
78
+ sleep 0.1
79
+ GC.start
80
+ sleep 0.1
81
+
82
+ count_objs = 0
83
+ ObjectSpace.each_object(RubyProcess) do |obj|
84
+ count_objs += 1
85
+ end
86
+
87
+ count_proxy_objs = 0
88
+ ObjectSpace.each_object(RubyProcess::ProxyObject) do |obj|
89
+ count_proxy_objs += 1
90
+ end
91
+
92
+ count_objs.should be <= 1
93
+ RubyProcess::ClassProxy.constants.empty?.should eq true
94
+ end
95
+ end
@@ -2,38 +2,34 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe "RubyProcess" do
4
4
  it "should be able to do basic stuff" do
5
- Ruby_process::Cproxy.run do |data|
5
+ RubyProcess::ClassProxy.run do |data|
6
6
  sp = data[:subproc]
7
7
  sp.new(:String, "Wee")
8
-
8
+
9
9
  ts = []
10
-
10
+
11
11
  1.upto(50) do |tcount|
12
12
  ts << Thread.new do
13
13
  1.upto(250) do
14
14
  str = sp.new(:String, "Kasper Johansen")
15
-
16
- res1 = str.include?("Kasper")
15
+
16
+ str.__rp_marshal.should eq "Kasper Johansen"
17
17
  str << " More"
18
-
19
- res2 = str.include?("Johansen")
18
+
19
+ str.__rp_marshal.should include "Johansen"
20
20
  str << " Even more"
21
-
22
- res3 = str.include?("Christina")
21
+
22
+ str.__rp_marshal.should_not include "Christina"
23
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 "."
24
+
25
+ str.__rp_marshal.should eq "Kasper Johansen More Even more Much more"
30
26
  end
31
27
  end
32
28
  end
33
-
29
+
34
30
  ts.each do |t|
35
31
  t.join
36
32
  end
37
33
  end
38
34
  end
39
- end
35
+ end