right_popen 1.0.17 → 1.0.18

Sign up to get free protection for your applications and to get access to all the features.
@@ -56,8 +56,7 @@ module RightScale
56
56
  data = @handle.readpartial(4096)
57
57
  receive_data(data)
58
58
  end
59
- rescue Errno::EBADF
60
- rescue EOFError
59
+ rescue Errno::EBADF, EOFError, IOError
61
60
  end
62
61
  close_connection
63
62
  end
@@ -95,8 +94,7 @@ module RightScale
95
94
  data = @handle.readpartial(4096)
96
95
  receive_data(data)
97
96
  end
98
- rescue Errno::EBADF
99
- rescue EOFError
97
+ rescue Errno::EBADF, EOFError, IOError
100
98
  end
101
99
  close_connection
102
100
  end
@@ -133,36 +131,49 @@ module RightScale
133
131
  #
134
132
  # See RightScale.popen3
135
133
  def self.popen3_imp(options)
136
- GC.start # To garbage collect open file descriptors from passed executions
134
+ GC.start # To garbage collect open file descriptors from past executions
137
135
  EM.next_tick do
138
136
  process = RightPopen::Process.new(:environment => options[:environment] || {})
139
137
  process.fork(options[:command])
140
138
 
141
- status_handler = EM.attach(process.status_fd, StatusHandler, process.status_fd)
142
- stderr_handler = EM.attach(process.stderr, PipeHandler, process.stderr, options[:target],
143
- options[:stderr_handler])
144
- stdout_handler = EM.attach(process.stdout, PipeHandler, process.stdout, options[:target],
145
- options[:stdout_handler])
146
- stdin_handler = EM.attach(process.stdin, InputHandler, process.stdin, options[:input])
147
-
148
- options[:target].method(options[:pid_handler]).call(process.pid) if
149
- options.key? :pid_handler
150
-
151
- wait_timer = EM::PeriodicTimer.new(1) do
152
- value = ::Process.waitpid2(process.pid, Process::WNOHANG)
153
- unless value.nil?
154
- begin
155
- ignored, status = value
156
- options[:target].method(options[:exit_handler]).call(status) if
157
- options[:exit_handler]
158
- ensure
159
- stdin_handler.drain_and_close
160
- stdout_handler.drain_and_close
161
- stderr_handler.drain_and_close
162
- status_handler.drain_and_close
163
- wait_timer.cancel
164
- end
139
+ handlers = []
140
+ handlers << EM.attach(process.status_fd, StatusHandler, process.status_fd)
141
+ handlers << EM.attach(process.stderr, PipeHandler, process.stderr, options[:target],
142
+ options[:stderr_handler])
143
+ handlers << EM.attach(process.stdout, PipeHandler, process.stdout, options[:target],
144
+ options[:stdout_handler])
145
+ handlers << EM.attach(process.stdin, InputHandler, process.stdin, options[:input])
146
+
147
+ options[:target].method(options[:pid_handler]).call(process.pid) if options.key? :pid_handler
148
+
149
+ handle_exit(process.pid, 0.1, handlers, options)
150
+ end
151
+ true
152
+ end
153
+
154
+ # Wait for process to exit and then call exit handler
155
+ # If no exit detected, double the wait time up to a maximum of 2 seconds
156
+ #
157
+ # === Parameters
158
+ # pid(Integer):: Process identifier
159
+ # wait_time(Fixnum):: Amount of time to wait before checking status
160
+ # handlers(Array):: Handlers for status, stderr, stdout, and stdin
161
+ # options[:exit_handler](Symbol):: Handler to be called when process exits
162
+ # options[:target](Object):: Object initiating command execution
163
+ #
164
+ # === Return
165
+ # true:: Always return true
166
+ def self.handle_exit(pid, wait_time, handlers, options)
167
+ EM::Timer.new(wait_time) do
168
+ if value = Process.waitpid2(pid, Process::WNOHANG)
169
+ begin
170
+ ignored, status = value
171
+ options[:target].method(options[:exit_handler]).call(status) if options[:exit_handler]
172
+ ensure
173
+ handlers.each { |h| h.drain_and_close }
165
174
  end
175
+ else
176
+ handle_exit(pid, [wait_time * 2, 1].min, handlers, options)
166
177
  end
167
178
  end
168
179
  true
@@ -23,6 +23,6 @@
23
23
 
24
24
  module RightScale
25
25
  module RightPopen
26
- VERSION = "1.0.17"
26
+ VERSION = "1.0.18"
27
27
  end
28
28
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: right_popen
3
3
  version: !ruby/object:Gem::Version
4
- hash: 53
5
- prerelease:
4
+ hash: 51
5
+ prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 17
10
- version: 1.0.17
9
+ - 18
10
+ version: 1.0.18
11
11
  platform: ruby
12
12
  authors:
13
13
  - Scott Messier
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2011-09-21 00:00:00 -07:00
20
+ date: 2011-12-02 00:00:00 -08:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency
@@ -154,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
154
  requirements: []
155
155
 
156
156
  rubyforge_project: right_popen
157
- rubygems_version: 1.6.2
157
+ rubygems_version: 1.3.7
158
158
  signing_key:
159
159
  specification_version: 3
160
160
  summary: Provides a platform-independent popen implementation