frontkick 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 21315e4ecfde359617b02081d2252b558e576acd
4
- data.tar.gz: 158fd87c5c96234c08ac944259b734d580f4a7bf
3
+ metadata.gz: 6086b0058c21edf9586f841eef70e15a746dbbaf
4
+ data.tar.gz: 0b1f63ed60327e2907dee507eaebe8ac9393df06
5
5
  SHA512:
6
- metadata.gz: cca5e9b8043cf202446b3592d3370f17b3d5bdbe490df40e0b82f90b852154e2c44e157e74a901ab26427ffcd07bf82ea43e9ecfca16a2840c3486d4e210252f
7
- data.tar.gz: 0cba11a2c72e2be354087dfb9d79c4df17ee2b737c6ad1c19457ce6dc78488a53d43dfa3b7804ec9a3c74c04633b766177ec59e64877497a07a5f2cd1640a3d4
6
+ metadata.gz: 170164a43b0a1a5175418a6c0216034a6b9d2e43637595699289bc9d100ef85767f466ef1dd2803eac27cd1c42cdbc825037ba807bab7fe3ab02bd3b70d48c5f
7
+ data.tar.gz: 5631ed597d2e5134fc5ef914f2bf51275485635b9fe6f022e50a34c070fa88b6b7f4117bc0aa9fbd73eb90d68c0f5e2d7f768248a13ef0d6f222c0617ea578bf
data/.travis.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  rvm:
2
- # - 1.8.7
3
- - 1.9.2
4
- - 1.9.3
5
2
  - 2.0.0
3
+ - 2.1.*
4
+ - 2.2.*
5
+ - 2.3.0
6
6
  gemfile:
7
7
  - Gemfile
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 0.5.2 (2016/03/18)
2
+
3
+ Fixes:
4
+
5
+ - Fix not to return exitstatus 0 when a child process is killed by -9 (Now, exitstatus becomes nil as Open3.popen3)
6
+
1
7
  # 0.5.1 (2016/01/23)
2
8
 
3
9
  Changes:
data/README.md CHANGED
@@ -1,7 +1,5 @@
1
1
  # frontkick [![Build Status](https://secure.travis-ci.org/sonots/frontkick.png?branch=master)](http://travis-ci.org/sonots/frontkick) [![Dependency Status](https://gemnasium.com/sonots/frontkick.png)](https://gemnasium.com/sonots/frontkick)
2
2
 
3
- testing ruby: 1.9.2, 1.9.3, 2.0.0;
4
-
5
3
  Frontkick is a gem to execute a command and obtain exit\_code, stdout, stderr simply.
6
4
 
7
5
  ## What is This For?
@@ -72,35 +70,33 @@ Other options such as :chdir are treated as options of `Open3.#popen3`.
72
70
 
73
71
  ### Kill Child Process
74
72
 
75
- To kill your frontkick process with its kicked child process, send signal to their signal group as
73
+ Sending a signal to a kicked child process is fine because a frontkick process can finish.
74
+ But, sending a signal to a frontkick process is not fine because a child process would become an orphan process.
75
+
76
+ To kill your frontkick process with its child process correctly, send a signal to their **process group** as
76
77
 
77
78
  kill -TERM -{PGID}
78
79
 
79
80
  You can find PGID like `ps -eo pid,pgid,command`.
80
81
 
81
- If you can not send a signal to a signal group by some reasons, handle signal by yourself as
82
+ If you can not take such an approach by some reasons (for example, `daemontools`, a process management tool,
83
+ does not support to send a signal to a process group), handle signal by yourself as
82
84
 
83
85
  ```ruby
84
86
  Frontkick.exec(["sleep 100"]) do |wait_thr|
85
87
  pid = wait_thr.pid
86
88
  trap :INT do
87
89
  Process.kill(:TERM, pid)
88
- # wait child processes finish
89
- begin
90
- pid, status = Process.waitpid2(pid)
91
- rescue Errno::ECHILD => e
92
- end
93
90
  exit 130
94
91
  end
95
92
  trap :TERM do
96
93
  Process.kill(:TERM, pid)
97
- Frontkick.process_wait(pid) # same with above
98
94
  exit 143
99
95
  end
100
96
  end
101
97
  ```
102
98
 
103
- More sophisticated example is available at [./example/kill_child.rb]
99
+ More sophisticated example is available at [./example/kill_child.rb](./example/kill_child.rb)
104
100
 
105
101
  ## Contributing
106
102
 
@@ -1,51 +1,77 @@
1
1
  require 'frontkick'
2
2
 
3
- puts "kill -TERM #{Process.pid} or Hit Ctrl-C in 10 seconds"
3
+ class SignalHandler
4
+ def self.register
5
+ @pids ||= []
6
+ @main_threads ||= []
4
7
 
5
- result = Frontkick.exec(["sleep 10"]) do |wait_thr|
6
- pid = wait_thr.pid
7
- signal_pipe_r, signal_pipe_w = IO.pipe
8
+ if @signal_pipe_r.nil? and @signal_pipe_w.nil?
9
+ @signal_pipe_r, @signal_pipe_w = IO.pipe
10
+ end
11
+
12
+ # For example, loogger `can't be called from trap context`
13
+ trap :INT do
14
+ @signal_pipe_w.puts 'INT'
15
+ end
16
+ trap :TERM do
17
+ @signal_pipe_w.puts 'TERM'
18
+ end
8
19
 
9
- # You know, there are many things `can't be called from trap context`
10
- trap :INT do
11
- signal_pipe_w.puts 'INT'
20
+ # Create a new thread to handle signals
21
+ # This example kills child (and self)
22
+ @signal_handler_thr ||= Thread.new do
23
+ begin
24
+ while readable_io = IO.select([@signal_pipe_r])
25
+ signal = readable_io.first[0].gets.strip
26
+ puts "#{signal} signal received"
27
+ @pids.each_with_index do |pid, idx|
28
+ main_thread = @main_threads[idx]
29
+ begin
30
+ puts "kill -#{signal} #{pid}"
31
+ Process.kill(signal, pid) rescue nil
32
+ rescue => e
33
+ main_thread.raise e
34
+ end
35
+ end
36
+ # case signal
37
+ # when 'INT'
38
+ # Kernel.exit(130)
39
+ # when 'TERM'
40
+ # Kernel.exit(148)
41
+ # end
42
+ end
43
+ rescue Exception => e
44
+ Thread.main.raise e
45
+ end
46
+ end
12
47
  end
13
- trap :TERM do
14
- signal_pipe_w.puts 'TERM'
48
+
49
+ def self.push(pid)
50
+ @pids << pid
51
+ @main_threads << Thread.current
15
52
  end
16
53
 
17
- # Create a new thread to handle signals
18
- # This example kills child and self
19
- signal_handler_thr = Thread.new do
20
- readable_io = IO.select([signal_pipe_r])
21
- signal = readable_io.first[0].gets.strip
22
- case signal
23
- when 'INT'
24
- puts "kill -INT #{pid}"
25
- Process.kill('INT', pid) rescue nil
26
- pid, status = Process.waitpid2(pid) rescue nil
27
- Kernel.exit(130)
28
- when 'TERM'
29
- puts "kill -TERM #{pid}"
30
- Process.kill('TERM', pid) rescue nil
31
- pid, status = Process.waitpid2(pid) rescue nil
32
- Kernel.exit(148)
33
- end
54
+ def self.pop(pid)
55
+ @pids -= [pid]
56
+ @main_threads -= [Thread.current]
34
57
  end
58
+ end
35
59
 
36
- begin
37
- # Wait child to finish (for normal situation)
38
- wait_thr.join
60
+ SignalHandler.register
39
61
 
40
- # Send NOOP to finish signal_handler_thr (for normal situation)
41
- signal_pipe_w.puts 'NOOP'
42
- signal_handler_thr.join
62
+ puts "## Frontkick started"
63
+ puts "kill -TERM #{Process.pid} or Hit Ctrl-C in 10 seconds"
64
+ result = Frontkick.exec(["sleep 10"]) do |wait_thr|
65
+ begin
66
+ SignalHandler.push(wait_thr.pid)
67
+ puts wait_thr.value # wait child to finish (for normal situation)
43
68
  ensure
44
- signal_pipe_r.close rescue nil
45
- signal_pipe_w.close rescue nil
69
+ SignalHandler.pop(wait_thr.pid)
46
70
  end
47
71
  end
48
72
 
49
- # should come here if child process finished normally,
50
- # but not come here if signals are received (Kernel.exit)
73
+ puts "## Fronkick finished"
74
+ puts "kill -TERM #{Process.pid} or Hit Ctrl-C in 5 seconds"
75
+ sleep 5
76
+
51
77
  puts result.inspect
File without changes
File without changes
data/example/run.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'frontkick'
2
2
 
3
3
  result = Frontkick.exec(["#{__dir__}/../experiment/cat_64k.rb"])
4
- puts result.stdout
4
+ puts "exitstatus: #{result.exitstatus}"
5
+ puts "stdout: #{result.stdout}"
@@ -9,7 +9,7 @@ module Frontkick
9
9
  def initialize(params = {})
10
10
  @stdout = params[:stdout] || ""
11
11
  @stderr = params[:stderr] || ""
12
- @exit_code = params[:exit_code] || 0
12
+ @exit_code = params[:exit_code] # exit_code would be nil if child process is killed -9
13
13
  @duration = params[:duration] || 0
14
14
  end
15
15
 
@@ -1,3 +1,3 @@
1
1
  module Frontkick
2
- VERSION = "0.5.1"
2
+ VERSION = "0.5.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: frontkick
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Naotoshi Seo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-23 00:00:00.000000000 Z
11
+ date: 2016-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -69,9 +69,9 @@ files:
69
69
  - Rakefile
70
70
  - example/dry_run.rb
71
71
  - example/kill_child.rb
72
- - example/out_err.rb
72
+ - example/popen3_options.rb
73
+ - example/redirect_without_shell.rb
73
74
  - example/run.rb
74
- - example/spawn_opts.rb
75
75
  - experiment/capture3_no_deadlock.rb
76
76
  - experiment/cat_63k.rb
77
77
  - experiment/cat_64k.rb