]> git.cworth.org Git - sup/blob - lib/sup/interactive-lock.rb
Merge branch 'buffer-rolling'
[sup] / lib / sup / interactive-lock.rb
1 require 'fileutils'
2
3 module Redwood
4
5 ## wrap a nice interactive layer on top of anything that has a #lock method
6 ## which throws a LockError which responds to #user, #host, #mtim, #pname, and
7 ## #pid.
8
9 module InteractiveLock
10   def pluralize number_of, kind; "#{number_of} #{kind}" + (number_of == 1 ? "" : "s") end
11
12   def time_ago_in_words time
13     secs = (Time.now - time).to_i
14     mins = secs / 60
15     time = if mins == 0
16       pluralize secs, "second"
17     else
18       pluralize mins, "minute"
19     end
20   end
21
22   DELAY = 5 # seconds
23
24   def lock_interactively stream=$stderr
25     begin
26       Index.lock
27     rescue Index::LockError => e
28       stream.puts <<EOS
29 Error: the index is locked by another process! User '#{e.user}' on
30 host '#{e.host}' is running #{e.pname} with pid #{e.pid}.
31 The process was alive as of at least #{time_ago_in_words e.mtime} ago.
32
33 EOS
34       stream.print "Should I ask that process to kill itself (y/n)? "
35       stream.flush
36
37       success = if $stdin.gets =~ /^\s*y(es)?\s*$/i
38         stream.puts "Ok, trying to kill process..."
39
40         begin
41           Process.kill "TERM", e.pid.to_i
42           sleep DELAY
43         rescue Errno::ESRCH # no such process
44           stream.puts "Hm, I couldn't kill it."
45         end
46
47         stream.puts "Let's try that again."
48         begin
49           Index.lock
50         rescue Index::LockError => e
51           stream.puts "I couldn't lock the index. The lockfile might just be stale."
52           stream.print "Should I just remove it and continue? (y/n) "
53           stream.flush
54
55           if $stdin.gets =~ /^\s*y(es)?\s*$/i
56             FileUtils.rm e.path
57
58             stream.puts "Let's try that one more time."
59             begin
60               Index.lock
61               true
62             rescue Index::LockError => e
63             end
64           end
65         end
66       end
67
68       stream.puts "Sorry, couldn't unlock the index." unless success
69       success
70     end
71   end
72 end
73
74 end