Permalink
Browse files

Merge branch 'master' of https://github.com/bdurand/cocaine

  • Loading branch information...
2 parents f77c1b5 + 98dff3d commit cccc67aca6f023fd1d3c77256fd787a6f99ace96 @mike-burns mike-burns committed Mar 16, 2012
Showing with 44 additions and 4 deletions.
  1. +3 −0 README.md
  2. +1 −0 cocaine.gemspec
  3. +10 −1 lib/cocaine/command_line.rb
  4. +30 −3 spec/cocaine/command_line_spec.rb
View
3 README.md
@@ -119,6 +119,9 @@ But you don't have to, as you saw above where it doesn't use this. But you CAN l
Cocaine::CommandLine.logger = Logger.new(STDOUT)
Cocaine::CommandLine.new("date").run # => Logs this -> Command :: date
```
+## POSIX Spawn
+
+You can potentially increase performance by installing the posix-spawn gem (https://rubygems.org/gems/posix-spawn). This gem can keep your application's heap from being copied when forking command line processesG. For applications with large heaps the gain can be significant. To include posix-spawn, simply add it to your Gemfile or, if you don't use bundler, install the gem.
## License
View
1 cocaine.gemspec
@@ -20,5 +20,6 @@ Gem::Specification.new do |s|
s.add_development_dependency('bourne')
s.add_development_dependency('mocha')
s.add_development_dependency('rake')
+ s.add_development_dependency('posix-spawn')
end
View
11 lib/cocaine/command_line.rb
@@ -1,5 +1,13 @@
module Cocaine
class CommandLine
+ # Check for posix-spawn gem. If it is available it will prevent the invoked processes
+ # from getting a copy of the ruby heap which can lead to significant performance gains.
+ begin
+ require 'posix/spawn'
+ rescue LoadError => e
+ # posix-spawn gem not available
+ end
+
class << self
attr_accessor :path, :logger
end
@@ -14,6 +22,7 @@ def initialize(binary, params = "", options = {})
@swallow_stderr = @options.delete(:swallow_stderr)
@expected_outcodes = @options.delete(:expected_outcodes)
@expected_outcodes ||= [0]
+ extend(POSIX::Spawn) if defined?(POSIX::Spawn)
end
def command
@@ -29,7 +38,7 @@ def run
begin
with_modified_path do
@logger.info("\e[32mCommand\e[0m :: #{command}") if @logger
- output = self.class.send(:'`', command)
+ output = send(:'`', command)
end
rescue Errno::ENOENT
raise Cocaine::CommandNotFoundError
View
33 spec/cocaine/command_line_spec.rb
@@ -113,15 +113,15 @@
it "runs the command it's given and return the output" do
cmd = Cocaine::CommandLine.new("convert", "a.jpg b.png", :swallow_stderr => false)
- cmd.class.stubs(:"`").with("convert a.jpg b.png").returns(:correct_value)
+ cmd.stubs(:"`").with("convert a.jpg b.png").returns(:correct_value)
with_exitstatus_returning(0) do
cmd.run.should == :correct_value
end
end
it "raises a CommandLineError if the result code from the command isn't expected" do
cmd = Cocaine::CommandLine.new("convert", "a.jpg b.png", :swallow_stderr => false)
- cmd.class.stubs(:"`").with("convert a.jpg b.png").returns(:correct_value)
+ cmd.stubs(:"`").with("convert a.jpg b.png").returns(:correct_value)
with_exitstatus_returning(1) do
lambda do
cmd.run
@@ -134,7 +134,7 @@
"a.jpg b.png",
:expected_outcodes => [0, 1],
:swallow_stderr => false)
- cmd.class.stubs(:"`").with("convert a.jpg b.png").returns(:correct_value)
+ cmd.stubs(:"`").with("convert a.jpg b.png").returns(:correct_value)
with_exitstatus_returning(1) do
lambda do
cmd.run
@@ -184,4 +184,31 @@
cmd = Cocaine::CommandLine.new("echo", "'Logging!'", :logger => nil)
lambda { cmd.run }.should_not raise_error
end
+
+ describe "command execution" do
+ it "should use the ` method to invoke the command line" do
+ cmd = Cocaine::CommandLine.new("echo", "hello")
+ cmd.stubs(:`).with(anything).returns(nil)
+ cmd.run
+ cmd.should have_received(:`).with("echo hello")
+ end
+
+ it "should use POSIX::Spawn to create processes if it is available" do
+ cmd = Cocaine::CommandLine.new("echo", "hello")
+ cmd.method(:`).owner.should == POSIX::Spawn
+ cmd.run.chomp.should == "hello"
+ end
+
+ it "should use the default Kernel spawning to create processes if POSIX::Spawn is not available" do
+ spawn = POSIX::Spawn
+ POSIX.send(:remove_const, :Spawn)
+ begin
+ cmd = Cocaine::CommandLine.new("echo", "hello")
+ cmd.method(:`).owner.should == Kernel
+ cmd.run.chomp.should == "hello"
+ ensure
+ POSIX.const_set(:Spawn, spawn)
+ end
+ end
+ end
end

0 comments on commit cccc67a

Please sign in to comment.