subexec 0.0.1

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.
Files changed (4) hide show
  1. data/README.rdoc +29 -0
  2. data/VERSION +1 -0
  3. data/lib/subexec.rb +86 -0
  4. metadata +70 -0
data/README.rdoc ADDED
@@ -0,0 +1,29 @@
1
+ = Subexec
2
+ by Peter Kieltyka
3
+ http://github/nulayer/subexec
4
+
5
+ === Description
6
+
7
+ Subexec is a simple library that spawns an external command with
8
+ an optional timeout parameter. It relies on Ruby 1.9's Process.spawn
9
+ method. Also, it works with synchronous and asynchronous code.
10
+
11
+ Useful for libraries that are Ruby wrappers for CLI's. For example,
12
+ resizing images with ImageMagick's mogrify command sometimes stalls
13
+ and never returns control back to the original process. Enter Subexec.
14
+
15
+ === Usage
16
+
17
+ sub = Subexec.run "echo 'hello' && sleep 3", :timeout => 5
18
+ puts sub.output # returns: hello
19
+ puts sub.exitstatus # returns: 0
20
+
21
+ sub = Subexec.run "echo 'hello' && sleep 3", :timeout => 1
22
+ puts sub.output # returns:
23
+ puts sub.exitstatus # returns:
24
+
25
+
26
+ === Limitations
27
+
28
+ Supports only Ruby 1.9.
29
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/lib/subexec.rb ADDED
@@ -0,0 +1,86 @@
1
+ # = Subexec
2
+ # * by Peter Kieltyka
3
+ # * http://github/nulayer/subprocess
4
+ #
5
+ # === Description
6
+ #
7
+ # Subexec is a simple library that spawns an external command with
8
+ # an optional timeout parameter. It relies on Ruby 1.9's Process.spawn
9
+ # method. Also, it works with synchronous and asynchronous code.
10
+ #
11
+ # Useful for libraries that are Ruby wrappers for CLI's. For example,
12
+ # resizing images with ImageMagick's mogrify command sometimes stalls
13
+ # and never returns control back to the original process. Subexec
14
+ # executes mogrify and preempts if gets lost.
15
+ #
16
+ # === Usage
17
+ #
18
+ # # Print hello
19
+ # sub = Subexec.run "echo 'hello' && sleep 3", :timeout => 5
20
+ # puts sub.output # returns: hello
21
+ # puts sub.exitstatus # returns: 0
22
+ #
23
+ # # Timeout process after a second
24
+ # sub = Subexec.run "echo 'hello' && sleep 3", :timeout => 1
25
+ # puts sub.output # returns:
26
+ # puts sub.exitstatus # returns:
27
+
28
+ class Subexec
29
+
30
+ attr_accessor :pid
31
+ attr_accessor :command
32
+ attr_accessor :timeout
33
+ attr_accessor :timer
34
+ attr_accessor :output
35
+ attr_accessor :exitstatus
36
+
37
+ def self.run(command, options={})
38
+ new(command, options)
39
+ end
40
+
41
+ def initialize(command, options={})
42
+ self.command = command
43
+ self.timeout = options[:timeout] || -1 # default is to never timeout
44
+ run!
45
+ end
46
+
47
+ def run!
48
+ r, w = IO.pipe
49
+ self.pid = Process.spawn(command, STDERR=>STDOUT, STDOUT=>w)
50
+ w.close
51
+
52
+ self.timer = Time.now + timeout
53
+ timed_out = false
54
+
55
+ loop do
56
+ begin
57
+ flags = (timeout > 0 ? Process::WUNTRACED|Process::WNOHANG : 0)
58
+ ret = Process.waitpid(pid, flags)
59
+ rescue Errno::ECHILD
60
+ break
61
+ end
62
+
63
+ break if ret == pid
64
+ sleep 0.001
65
+ if Time.now > timer
66
+ timed_out = true
67
+ break
68
+ end
69
+ end
70
+
71
+ if timed_out
72
+ # The subprocess timed out -- kill it
73
+ Process.kill(9, pid) rescue Errno::ESRCH
74
+ self.exitstatus = nil
75
+ else
76
+ # The subprocess exited on its own
77
+ self.exitstatus = $?.exitstatus
78
+ self.output = r.readlines.join("")
79
+ end
80
+ r.close
81
+
82
+ self
83
+ end
84
+
85
+ end
86
+
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: subexec
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Peter Kieltyka
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-05-24 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Subexec spawns an external command with a timeout
23
+ email:
24
+ - peter@nulayer.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - README.rdoc
33
+ - VERSION
34
+ - lib/subexec.rb
35
+ has_rdoc: true
36
+ homepage: http://github.com/nulayer/subexec
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options: []
41
+
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ hash: 3
50
+ segments:
51
+ - 0
52
+ version: "0"
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.3.7
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: Subexec spawns an external command with a timeout
69
+ test_files: []
70
+