right_popen 1.0.17 → 1.0.18

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