restartable 0.1.2 → 0.1.3

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.
Files changed (5) hide show
  1. checksums.yaml +8 -8
  2. data/TODO +2 -1
  3. data/lib/restartable.rb +63 -36
  4. data/restartable.gemspec +1 -1
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZjBlMWMyMTgxZjllMGY4NTNkZGMzNTcxODY2ZjlmYTU5ZjA3MGNmMQ==
4
+ MWQ5YTBhNmJmNjQxOTdkZGRmZDlmOThhYWZmZmQ5MDY4OGJiMWM1Yw==
5
5
  data.tar.gz: !binary |-
6
- ZWE5Nzc2YjgxYTY2MjBjMDA4OGE1ZDcxZTVkNzk2Y2VlMDVmN2Q5NA==
6
+ ZjMwMzEyMzBhYzQ0NzMyZjgyZjM3YTBhMmMzZDU5OWNhNjU2MGQ0ZA==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- NDBkMmUxOTczOTQ5N2JlZDJjYzc1ZjMyOTc1YjgxYjNkMWMyMmEyMmJjODVl
10
- OTlhMzA5ZTFiNmM5MWVjMjUwYzFiNDk1ZjA1ZTJiMGU0ZDQ3ZjI2ZWFlNWQx
11
- MWYxNjRlZjZhN2Q3ZDU3YTliYjZjNjBjMTQ1YWEwMTNiMTcwYzQ=
9
+ NzAwZmI4M2VkMzU4ZTE1ZmE5MjJiYWFmNTFjMTI3MGMyM2UzZjYxMWMxYzI1
10
+ ZDdmN2U4M2IwODdmYjYyMjJmMDUzZjc2OTkwZDk5ODY0ZWFjY2I2ZWU3NWY2
11
+ MDk0MDBiMjFkNGM0MGQ2YmUwZmYwZmZjYTNhMDk4MGE2NDM4MjM=
12
12
  data.tar.gz: !binary |-
13
- NDU2NTA2M2M3N2M1YjBjZWE2ZWE5MzY5NzQxNjViYWU2ZjM1MDU3NmM2N2Ez
14
- MGRiZDE1YTE2MmM1N2MwYmQ0NTMwMTdjZTI0ZmVmNWY4NWFhNjU5NDM0ZGEz
15
- YTJmYjlhYWRmOGM4MDliMTQzN2Y5MGJiOTg0NDQzMmIyY2E4YWQ=
13
+ ZTczZDEwNzY1MDg3Y2VhOTI4OTVkNzA0NzlhM2FlMjYyN2VlYzhiODc4Yjlm
14
+ YmQ5NzFjYmMxNjA2N2ZjZTkzNzFkZTc0ODY4MTNlNGIzZGE5MDM3YjI2ZWVm
15
+ ZTM2ZDVhOGQxZmE2ZmZjODA4YTJiZDdiODVlMDcyZjY0MTE5ZTU=
data/TODO CHANGED
@@ -1,2 +1,3 @@
1
- run block on restart
1
+ add option to run block on restart
2
2
  bin option to run command on restart
3
+ option to auto restart when block finishes
data/lib/restartable.rb CHANGED
@@ -2,82 +2,109 @@
2
2
 
3
3
  require 'sys/proctable'
4
4
  require 'colored'
5
+ require 'thread'
5
6
 
6
7
  class Restartable
7
8
  def self.version
8
9
  Gem.loaded_specs['restartable'].version.to_s rescue 'DEV'
9
10
  end
10
11
 
11
- WAIT_SIGNALS = [[1, 'INT'], [1, 'INT'], [1, 'INT'], [1, 'TERM'], [5, 'KILL']]
12
-
13
12
  def initialize(options, &block)
14
13
  @options, @block = options, block
14
+ run!
15
+ end
16
+
17
+ private
18
+
19
+ def run!
15
20
  @mutex = Mutex.new
16
- synced_trap('INT'){ interrupt! }
17
- synced_trap('TERM'){ no_restart!; interrupt! }
21
+
22
+ receiver, sender = IO.pipe
23
+ @trap_sender = Process.fork do
24
+ receiver.close
25
+ Signal.trap('PIPE', 'EXIT')
26
+ synced_trap('INT'){ Marshal.dump(:int, sender) }
27
+ loop{ sleep }
28
+ end
29
+ sender.close
30
+
31
+ Signal.trap('INT', 'IGNORE')
32
+ synced_trap('TERM'){ terminate! }
33
+
34
+ int_receiver = Thread.new do
35
+ until receiver.eof?
36
+ Marshal.load(receiver) && interrupt!
37
+ end
38
+ end
18
39
  cycle
19
40
  end
20
41
 
21
42
  def interrupt!
22
43
  unless @interrupted
23
44
  @interrupted = true
24
- Thread.list.each do |thread|
25
- unless Thread.current == thread
26
- thread.raise SignalException.new('INT')
27
- end
45
+ (Thread.list - [Thread.current]).each do |thread|
46
+ thread.raise SignalException.new('INT')
28
47
  end
29
48
  else
30
49
  no_restart!
31
50
  end
32
51
  end
33
52
 
53
+ def terminate!
54
+ no_restart!
55
+ interrupt!
56
+ end
57
+
34
58
  def no_restart!
35
59
  @stop = true
36
60
  puts 'Don\'t restart!'.red.bold
37
61
  end
38
62
 
63
+ def synced_trap(signal, &block)
64
+ Signal.trap(signal) do
65
+ Thread.new do
66
+ @mutex.synchronize(&block)
67
+ end
68
+ end
69
+ end
70
+
71
+ WAIT_SIGNALS = [[5, 'INT'], [3, 'INT'], [1, 'INT'], [3, 'TERM'], [5, 'KILL']]
72
+
39
73
  def cycle
40
74
  until @stop
41
75
  @interrupted = false
42
76
  puts '^C to restart, double ^C to stop'.green
43
77
  begin
44
78
  @block.call
45
- sleep # wait ^C even if block finishes
79
+ loop{ sleep } # wait ^C even if block finishes
46
80
  rescue SignalException
47
- unless children.empty?
48
- puts 'Killing children…'.yellow.bold
49
- ripper = Thread.new do
50
- WAIT_SIGNALS.each do |time, signal|
51
- sleep time
52
- puts "…SIG#{signal}…".yellow
53
- children.each do |child|
54
- Process.kill(signal, child.pid)
55
- end
56
- end
57
- end
58
- Process.waitall
59
- ripper.terminate
60
- end
61
- unless @stop
62
- puts 'Waiting ^C 0.5 second than restart…'.yellow.bold
63
- sleep 0.5
64
- end
81
+ kill_children!
82
+ end
83
+ unless @stop
84
+ puts 'Waiting ^C 0.5 second than restart…'.yellow.bold
85
+ sleep 0.5
65
86
  end
66
87
  end
67
88
  end
68
89
 
69
- private
70
-
71
- def synced_trap(signal, &block)
72
- Signal.trap(signal) do
73
- Thread.new do
74
- @mutex.synchronize(&block)
90
+ def kill_children!
91
+ unless children_pids.empty?
92
+ puts 'Killing children…'.yellow.bold
93
+ ripper = Thread.new do
94
+ WAIT_SIGNALS.each do |time, signal|
95
+ sleep time
96
+ puts "…SIG#{signal}…".yellow
97
+ children_pids.each do |child_pid|
98
+ Process.kill(signal, child_pid)
99
+ end
100
+ end
75
101
  end
102
+ children_pids.each(&Process.method(:wait))
103
+ ripper.terminate
76
104
  end
77
105
  end
78
106
 
79
- def children
80
- pid = Process.pid
81
- Sys::ProcTable.ps.select{ |pe| pid == pe.ppid }
107
+ def children_pids
108
+ Sys::ProcTable.ps.select{ |pe| $$ == pe.ppid }.map(&:pid) - [@trap_sender]
82
109
  end
83
110
  end
data/restartable.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'restartable'
5
- s.version = '0.1.2'
5
+ s.version = '0.1.3'
6
6
  s.summary = %q{Run code, Ctrl-C to restart, once more Ctrl-C to stop}
7
7
  s.homepage = "http://github.com/toy/#{s.name}"
8
8
  s.authors = ['Ivan Kuchin']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restartable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Kuchin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-04-01 00:00:00.000000000 Z
11
+ date: 2013-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colored