ruby_process 0.0.9 → 0.0.13

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.
@@ -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