frontkick 0.5.1 → 0.5.2

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