engineyard-serverside 1.5.28.pre9 → 1.5.28.pre10

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,5 +1,5 @@
1
1
  module EY
2
2
  module Serverside
3
- VERSION = '1.5.28.pre9'
3
+ VERSION = '1.5.28.pre10'
4
4
  end
5
5
  end
@@ -17,13 +17,6 @@ module Celluloid
17
17
  if super.is_a? AbortError
18
18
  # Aborts are caused by caller error, so ensure they capture the
19
19
  # caller's backtrace instead of the receiver's
20
- p '#############'
21
- p '#############'
22
- p '#############'
23
- p super.cause.message
24
- p super.cause.backtrace.join("\n")
25
- p '#############'
26
- p '#############'
27
20
  raise super.cause.class.new(super.cause.message)
28
21
  else
29
22
  raise super
@@ -4,23 +4,65 @@ require 'timeout'
4
4
  require 'thread'
5
5
 
6
6
  module Open4
7
- #--{{{
8
- VERSION = '1.1.0'
7
+ VERSION = '1.3.0'
9
8
  def self.version() VERSION end
10
9
 
11
10
  class Error < ::StandardError; end
12
11
 
12
+ def pfork4(fun, &b)
13
+ Open4.do_popen(b, :block) do |ps_read, _|
14
+ ps_read.close
15
+ begin
16
+ fun.call
17
+ rescue SystemExit => e
18
+ # Make it seem to the caller that calling Kernel#exit in +fun+ kills
19
+ # the child process normally. Kernel#exit! bypasses this rescue
20
+ # block.
21
+ exit! e.status
22
+ else
23
+ exit! 0
24
+ end
25
+ end
26
+ end
27
+ module_function :pfork4
28
+
13
29
  def popen4(*cmd, &b)
14
- #--{{{
30
+ Open4.do_popen(b, :init) do |ps_read, ps_write|
31
+ ps_read.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
32
+ ps_write.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
33
+ exec(*cmd)
34
+ raise 'forty-two' # Is this really needed?
35
+ end
36
+ end
37
+ alias open4 popen4
38
+ module_function :popen4
39
+ module_function :open4
40
+
41
+ def popen4ext(closefds=false, *cmd, &b)
42
+ Open4.do_popen(b, :init, closefds) do |ps_read, ps_write|
43
+ ps_read.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
44
+ ps_write.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
45
+ exec(*cmd)
46
+ raise 'forty-two' # Is this really needed?
47
+ end
48
+ end
49
+ module_function :popen4ext
50
+
51
+ def self.do_popen(b = nil, exception_propagation_at = nil, closefds=false, &cmd)
15
52
  pw, pr, pe, ps = IO.pipe, IO.pipe, IO.pipe, IO.pipe
16
53
 
17
54
  verbose = $VERBOSE
18
55
  begin
19
56
  $VERBOSE = nil
20
- ps.first.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
21
- ps.last.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
22
57
 
23
58
  cid = fork {
59
+ if closefds
60
+ exlist = [0, 1, 2] | [pw,pr,pe,ps].map{|p| [p.first.fileno, p.last.fileno] }.flatten
61
+ ObjectSpace.each_object(IO){|io|
62
+ io.close if (not io.closed?) and (not exlist.include? io.fileno)
63
+ }
64
+ end
65
+
24
66
  pw.last.close
25
67
  STDIN.reopen pw.first
26
68
  pw.first.close
@@ -36,52 +78,59 @@ module Open4
36
78
  STDOUT.sync = STDERR.sync = true
37
79
 
38
80
  begin
39
- exec(*cmd)
40
- raise 'forty-two'
81
+ cmd.call(ps)
41
82
  rescue Exception => e
42
83
  Marshal.dump(e, ps.last)
43
84
  ps.last.flush
85
+ ensure
86
+ ps.last.close unless ps.last.closed?
44
87
  end
45
- ps.last.close unless (ps.last.closed?)
88
+
46
89
  exit!
47
90
  }
48
91
  ensure
49
92
  $VERBOSE = verbose
50
93
  end
51
94
 
52
- [pw.first, pr.last, pe.last, ps.last].each{|fd| fd.close}
95
+ [ pw.first, pr.last, pe.last, ps.last ].each { |fd| fd.close }
53
96
 
54
- begin
55
- e = Marshal.load ps.first
56
- raise(Exception === e ? e : "unknown failure!")
57
- rescue EOFError # If we get an EOF error, then the exec was successful
58
- 42
59
- ensure
60
- ps.first.close
61
- end
97
+ Open4.propagate_exception cid, ps.first if exception_propagation_at == :init
62
98
 
63
99
  pw.last.sync = true
64
100
 
65
- pi = [pw.last, pr.first, pe.first]
101
+ pi = [ pw.last, pr.first, pe.first ]
102
+
103
+ begin
104
+ return [cid, *pi] unless b
66
105
 
67
- if b
68
106
  begin
69
- b[cid, *pi]
70
- Process.waitpid2(cid).last
107
+ b.call(cid, *pi)
71
108
  ensure
72
- pi.each{|fd| fd.close unless fd.closed?}
109
+ pi.each { |fd| fd.close unless fd.closed? }
73
110
  end
74
- else
75
- [cid, pw.last, pr.first, pe.first]
111
+
112
+ Open4.propagate_exception cid, ps.first if exception_propagation_at == :block
113
+
114
+ Process.waitpid2(cid).last
115
+ ensure
116
+ ps.first.close unless ps.first.closed?
76
117
  end
77
- #--}}}
78
118
  end
79
- alias open4 popen4
80
- module_function :popen4
81
- module_function :open4
119
+
120
+ def self.propagate_exception(cid, ps_read)
121
+ e = Marshal.load ps_read
122
+ raise Exception === e ? e : "unknown failure!"
123
+ rescue EOFError
124
+ # Child process did not raise exception.
125
+ rescue
126
+ # Child process raised exception; wait it in order to avoid a zombie.
127
+ Process.waitpid2 cid
128
+ raise
129
+ ensure
130
+ ps_read.close
131
+ end
82
132
 
83
133
  class SpawnError < Error
84
- #--{{{
85
134
  attr 'cmd'
86
135
  attr 'status'
87
136
  attr 'signals'
@@ -98,11 +147,9 @@ module Open4
98
147
  sigs = @signals.map{|k,v| "#{ k }:#{ v.inspect }"}.join(' ')
99
148
  super "cmd <#{ cmd }> failed with status <#{ exitstatus.inspect }> signals <#{ sigs }>"
100
149
  end
101
- #--}}}
102
150
  end
103
151
 
104
152
  class ThreadEnsemble
105
- #--{{{
106
153
  attr 'threads'
107
154
 
108
155
  def initialize cid
@@ -154,18 +201,14 @@ module Open4
154
201
  def all_done
155
202
  @threads.size.times{ @done.pop }
156
203
  end
157
- #--}}}
158
204
  end
159
205
 
160
206
  def to timeout = nil
161
- #--{{{
162
207
  Timeout.timeout(timeout){ yield }
163
- #--}}}
164
208
  end
165
209
  module_function :to
166
210
 
167
211
  def new_thread *a, &b
168
- #--{{{
169
212
  cur = Thread.current
170
213
  Thread.new(*a) do |*a|
171
214
  begin
@@ -174,29 +217,25 @@ module Open4
174
217
  cur.raise e
175
218
  end
176
219
  end
177
- #--}}}
178
220
  end
179
221
  module_function :new_thread
180
222
 
181
223
  def getopts opts = {}
182
- #--{{{
183
224
  lambda do |*args|
184
225
  keys, default, ignored = args
185
- catch('opt') do
226
+ catch(:opt) do
186
227
  [keys].flatten.each do |key|
187
228
  [key, key.to_s, key.to_s.intern].each do |key|
188
- throw 'opt', opts[key] if opts.has_key?(key)
229
+ throw :opt, opts[key] if opts.has_key?(key)
189
230
  end
190
231
  end
191
232
  default
192
233
  end
193
234
  end
194
- #--}}}
195
235
  end
196
236
  module_function :getopts
197
237
 
198
238
  def relay src, dst = nil, t = nil
199
- #--{{{
200
239
  send_dst =
201
240
  if dst.respond_to?(:call)
202
241
  lambda{|buf| dst.call(buf)}
@@ -244,12 +283,10 @@ module Open4
244
283
  send_dst[buf]
245
284
  end
246
285
  end
247
- #--}}}
248
286
  end
249
287
  module_function :relay
250
288
 
251
289
  def spawn arg, *argv
252
- #--{{{
253
290
  argv.unshift(arg)
254
291
  opts = ((argv.size > 1 and Hash === argv.last) ? argv.pop : {})
255
292
  argv.flatten!
@@ -325,7 +362,6 @@ module Open4
325
362
  (ignore_exit_failure or (status.nil? and ignore_exec_failure) or exitstatus.include?(status.exitstatus))
326
363
 
327
364
  status
328
- #--}}}
329
365
  end
330
366
  module_function :spawn
331
367
 
@@ -336,7 +372,6 @@ module Open4
336
372
  module_function :chdir
337
373
 
338
374
  def background arg, *argv
339
- #--{{{
340
375
  require 'thread'
341
376
  q = Queue.new
342
377
  opts = { 'pid' => q, :pid => q }
@@ -354,14 +389,12 @@ module Open4
354
389
  define_method(:exitstatus){ @exitstatus ||= spawn_status.exitstatus }
355
390
  }
356
391
  thread
357
- #--}}}
358
392
  end
359
393
  alias bg background
360
394
  module_function :background
361
395
  module_function :bg
362
396
 
363
397
  def maim pid, opts = {}
364
- #--{{{
365
398
  getopt = getopts opts
366
399
  sigs = getopt[ 'signals', %w(SIGTERM SIGQUIT SIGKILL) ]
367
400
  suspend = getopt[ 'suspend', 4 ]
@@ -379,12 +412,10 @@ module Open4
379
412
  return true unless alive? pid
380
413
  end
381
414
  return(not alive?(pid))
382
- #--}}}
383
415
  end
384
416
  module_function :maim
385
417
 
386
418
  def alive pid
387
- #--{{{
388
419
  pid = Integer pid
389
420
  begin
390
421
  Process.kill 0, pid
@@ -392,12 +423,10 @@ module Open4
392
423
  rescue Errno::ESRCH
393
424
  false
394
425
  end
395
- #--}}}
396
426
  end
397
427
  alias alive? alive
398
428
  module_function :alive
399
429
  module_function :'alive?'
400
- #--}}}
401
430
  end
402
431
 
403
432
  def open4(*cmd, &b) cmd.size == 0 ? Open4 : Open4::popen4(*cmd, &b) end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: engineyard-serverside
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.28.pre9
4
+ version: 1.5.28.pre10
5
5
  prerelease: 7
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-02-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &2158606880 !ruby/object:Gem::Requirement
16
+ requirement: &2159950880 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - =
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.3.2
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *2158606880
24
+ version_requirements: *2159950880
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &2158606380 !ruby/object:Gem::Requirement
27
+ requirement: &2159950220 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.9.2.2
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2158606380
35
+ version_requirements: *2159950220
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rdoc
38
- requirement: &2158606000 !ruby/object:Gem::Requirement
38
+ requirement: &2159949640 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2158606000
46
+ version_requirements: *2159949640
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: timecop
49
- requirement: &2158605540 !ruby/object:Gem::Requirement
49
+ requirement: &2159949180 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2158605540
57
+ version_requirements: *2159949180
58
58
  description:
59
59
  email: cloud@engineyard.com
60
60
  executables: