]> git.cworth.org Git - sup/commitdiff
Merge branch 'locking-refactor'
authorWilliam Morgan <wmorgan-sup@masanjin.net>
Tue, 25 Aug 2009 13:51:15 +0000 (09:51 -0400)
committerWilliam Morgan <wmorgan-sup@masanjin.net>
Tue, 25 Aug 2009 13:51:38 +0000 (09:51 -0400)
Conflicts:
bin/sup
bin/sup-sync-back
bin/sup-tweak-labels
lib/sup.rb
lib/sup/suicide.rb

Manifest.txt
bin/sup
bin/sup-add
bin/sup-sync
bin/sup-sync-back
bin/sup-tweak-labels
lib/sup.rb
lib/sup/index.rb
lib/sup/interactive-lock.rb [new file with mode: 0644]
lib/sup/suicide.rb [deleted file]
lib/sup/util.rb

index be633d776e2b1e5165edeac4d7631cf714471207..09d867eb47595a3ad8a1a7e693734e9f201cb983 100644 (file)
@@ -32,6 +32,7 @@ lib/sup/index.rb
 lib/sup/keymap.rb
 lib/sup/label.rb
 lib/sup/logger.rb
+lib/sup/interactive-lock.rb
 lib/sup/maildir.rb
 lib/sup/mbox.rb
 lib/sup/mbox/loader.rb
@@ -67,7 +68,6 @@ lib/sup/poll.rb
 lib/sup/rfc2047.rb
 lib/sup/sent.rb
 lib/sup/source.rb
-lib/sup/suicide.rb
 lib/sup/tagger.rb
 lib/sup/textfield.rb
 lib/sup/thread.rb
diff --git a/bin/sup b/bin/sup
index 8a377f78149f5a4b17a56e06036fcae96e2b3fb6..bbb6c1711a7d5f580530a95859b4853649bf69c9 100755 (executable)
--- a/bin/sup
+++ b/bin/sup
@@ -131,37 +131,14 @@ end
 module_function :start_cursing, :stop_cursing
 
 Index.init
-begin
-  Index.lock
-rescue Index::LockError => e
-  require 'highline'
-
-  h = HighLine.new
-  h.wrap_at = :auto
-  h.say Index.fancy_lock_error_message_for(e)
-
-  case h.ask("Should I ask that process to kill itself? ")
-  when /^\s*y(es)?\s*$/i
-    h.say "Ok, suggesting seppuku..."
-    FileUtils.touch Redwood::SUICIDE_FN
-    sleep SuicideManager::DELAY * 2
-    FileUtils.rm_f Redwood::SUICIDE_FN
-    h.say "Let's try that again."
-    retry
-  else
-    h.say <<EOS
-Ok, giving up. If the process crashed and left a stale lockfile, you
-can fix this by manually deleting #{Index.lockfile}.
-EOS
-    exit
-  end
-end
+Index.lock_interactively or exit
 
 begin
   Redwood::start
   Index.load
 
-  trap("TERM") { |x| SuicideManager.please_die! }
+  $die = false
+  trap("TERM") { |x| $die = true }
   trap("WINCH") { |x| BufferManager.sigwinch_happened! }
 
   if(s = Redwood::SourceManager.source_for DraftManager.source_name)
@@ -219,7 +196,6 @@ begin
 
   unless $opts[:no_threads]
     PollManager.start
-    SuicideManager.start
     Index.start_lock_update_thread
   end
 
@@ -227,7 +203,7 @@ begin
     SearchResultsMode.spawn_from_query $opts[:search]
   end
 
-  until Redwood::exceptions.nonempty? || SuicideManager.die?
+  until Redwood::exceptions.nonempty? || $die
     c = begin
       Ncurses.nonblocking_getch
     rescue Interrupt => e
@@ -328,13 +304,12 @@ begin
     bm.draw_screen
   end
 
-  bm.kill_all_buffers if SuicideManager.die?
+  bm.kill_all_buffers if $die
 rescue Exception => e
   Redwood::record_exception e, "main"
 ensure
   unless $opts[:no_threads]
     PollManager.stop if PollManager.instantiated?
-    SuicideManager.stop if PollManager.instantiated?
     Index.stop_lock_update_thread
   end
 
@@ -346,7 +321,7 @@ ensure
   Redwood::Logger.add_sink $stderr, false
   debug "stopped cursing"
 
-  if SuicideManager.instantiated? && SuicideManager.die?
+  if $die
     info "I've been ordered to commit seppuku. I obey!"
   end
 
index 8f7010ee3f4dc06aa9051006ab08a4f45a42bec9..e27a0ebf6ff446a9347d4fd8937653ab45b97db8 100755 (executable)
@@ -79,7 +79,7 @@ $terminal.wrap_at = :auto
 Redwood::start
 index = Redwood::Index.init
 
-index.lock_or_die
+index.lock_interactively or exit
 
 begin
   Redwood::SourceManager.load_sources
index b743c1c13e3cdf9f73d6d24a5c88882985c30681..2aa00c3720bcd0dbbce60499e5d14a70e01ae418 100755 (executable)
@@ -112,7 +112,7 @@ else
 end
 
 seen = {}
-index.lock_or_die
+index.lock_interactively or exit
 begin
   index.load
 
index 4d76f17f587fb75e4294b4a39c4bf52f0d5280c8..6298c97c3e6190e8704ff2cd1333843f09511fea 100755 (executable)
@@ -66,7 +66,7 @@ end
 
 Redwood::start
 index = Redwood::Index.init
-index.lock_or_die
+index.lock_interactively or exit
 
 deleted_fp, spam_fp = nil
 unless opts[:dry_run]
index 138f7e1738c7c6029ceb40003716d71763be53ab..90f6a57ddb0cbebd037f4a74dd1692a191de522e 100755 (executable)
@@ -58,10 +58,12 @@ add_labels = opts[:add].to_set_of_symbols ","
 remove_labels = opts[:remove].to_set_of_symbols ","
 
 Trollop::die "nothing to do: no labels to add or remove" if add_labels.empty? && remove_labels.empty?
+Trollop::die "no sources specified" if ARGV.empty?
 
 Redwood::start
+index = Redwood::Index.init
+index.lock_interactively or exit
 begin
-  index = Redwood::Index.init
   index.load
 
   source_ids = if opts[:all_sources]
index 43daa7e7be19b0ba12c83bec1d67c5f50d0b6d94..16c2b3f3bbf802d6e713714a48aecbde41ad8dc2 100644 (file)
@@ -126,7 +126,6 @@ module Redwood
     Redwood::DraftManager.init Redwood::DRAFT_DIR
     Redwood::UpdateManager.init
     Redwood::PollManager.init
-    Redwood::SuicideManager.init Redwood::SUICIDE_FN
     Redwood::CryptoManager.init
     Redwood::UndoManager.init
     Redwood::SourceManager.init
@@ -265,7 +264,6 @@ require "sup/modes/scroll-mode"
 require "sup/modes/text-mode"
 require "sup/modes/log-mode"
 require "sup/update"
-require "sup/suicide"
 require "sup/message-chunks"
 require "sup/message"
 require "sup/source"
@@ -275,6 +273,7 @@ require "sup/imap"
 require "sup/person"
 require "sup/account"
 require "sup/thread"
+require "sup/interactive-lock"
 require "sup/index"
 require "sup/textfield"
 require "sup/colormap"
index dfaeee819c1db70f410de829f001ccf21c19280c..ff03f195f6bca74aefdb23eedecc01c2172ee39c 100644 (file)
@@ -13,6 +13,8 @@ end
 module Redwood
 
 class BaseIndex
+  include InteractiveLock
+
   class LockError < StandardError
     def initialize h
       @h = h
@@ -53,42 +55,6 @@ class BaseIndex
     @lock_update_thread = nil
   end
 
-  def possibly_pluralize number_of, kind
-    "#{number_of} #{kind}" +
-        if number_of == 1 then "" else "s" end
-  end
-
-  def fancy_lock_error_message_for e
-    secs = (Time.now - e.mtime).to_i
-    mins = secs / 60
-    time =
-      if mins == 0
-        possibly_pluralize secs , "second"
-      else
-        possibly_pluralize mins, "minute"
-      end
-
-    <<EOS
-Error: the sup index is locked by another process! User '#{e.user}' on
-host '#{e.host}' is running #{e.pname} with pid #{e.pid}. The process was alive
-as of #{time} ago.
-EOS
-  end
-
-  def lock_or_die
-    begin
-      lock
-    rescue LockError => e
-      $stderr.puts fancy_lock_error_message_for(e)
-      $stderr.puts <<EOS
-
-You can wait for the process to finish, or, if it crashed and left a
-stale lock file behind, you can manually delete #{@lock.path}.
-EOS
-      exit
-    end
-  end
-
   def unlock
     if @lock && @lock.locked?
       debug "unlocking #{lockfile}..."
diff --git a/lib/sup/interactive-lock.rb b/lib/sup/interactive-lock.rb
new file mode 100644 (file)
index 0000000..92a5ead
--- /dev/null
@@ -0,0 +1,74 @@
+require 'fileutils'
+
+module Redwood
+
+## wrap a nice interactive layer on top of anything that has a #lock method
+## which throws a LockError which responds to #user, #host, #mtim, #pname, and
+## #pid.
+
+module InteractiveLock
+  def pluralize number_of, kind; "#{number_of} #{kind}" + (number_of == 1 ? "" : "s") end
+
+  def time_ago_in_words time
+    secs = (Time.now - time).to_i
+    mins = secs / 60
+    time = if mins == 0
+      pluralize secs, "second"
+    else
+      pluralize mins, "minute"
+    end
+  end
+
+  DELAY = 5 # seconds
+
+  def lock_interactively stream=$stderr
+    begin
+      Index.lock
+    rescue Index::LockError => e
+      stream.puts <<EOS
+Error: the index is locked by another process! User '#{e.user}' on
+host '#{e.host}' is running #{e.pname} with pid #{e.pid}.
+The process was alive as of at least #{time_ago_in_words e.mtime} ago.
+
+EOS
+      stream.print "Should I ask that process to kill itself (y/n)? "
+      stream.flush
+
+      success = if $stdin.gets =~ /^\s*y(es)?\s*$/i
+        stream.puts "Ok, trying to kill process..."
+
+        begin
+          Process.kill "TERM", e.pid.to_i
+          sleep DELAY
+        rescue Errno::ESRCH # no such process
+          stream.puts "Hm, I couldn't kill it."
+        end
+
+        stream.puts "Let's try that again."
+        begin
+          Index.lock
+        rescue Index::LockError => e
+          stream.puts "I couldn't lock the index. The lockfile might just be stale."
+          stream.print "Should I just remove it and continue? (y/n) "
+          stream.flush
+
+          if $stdin.gets =~ /^\s*y(es)?\s*$/i
+            FileUtils.rm e.path
+
+            stream.puts "Let's try that one more time."
+            begin
+              Index.lock
+              true
+            rescue Index::LockError => e
+            end
+          end
+        end
+      end
+
+      stream.puts "Sorry, couldn't unlock the index." unless success
+      success
+    end
+  end
+end
+
+end
diff --git a/lib/sup/suicide.rb b/lib/sup/suicide.rb
deleted file mode 100644 (file)
index 09fc7b8..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-module Redwood
-
-class SuicideManager
-  include Singleton
-
-  DELAY = 5
-
-  def initialize fn
-    @fn = fn
-    @die = false
-    @thread = nil
-    FileUtils.rm_f @fn
-  end
-
-  bool_reader :die
-  def please_die!; @die = true end
-
-  def start
-    @thread = Redwood::reporting_thread("suicide watch") do
-      while true
-        sleep DELAY
-        if File.exists? @fn
-          FileUtils.rm_f @fn
-          @die = true
-        end
-      end
-    end
-  end
-
-  def stop
-    @thread.kill if @thread
-    @thread = nil
-  end
-end
-
-end
index 9282f64133a382cef899f57fd62a403310fe8d7f..068ce6bad904c9012bdcd5d8883ac48a68e59976 100644 (file)
@@ -25,6 +25,7 @@ class Lockfile
   def lockinfo_on_disk
     h = load_lock_id IO.read(path)
     h['mtime'] = File.mtime path
+    h['path'] = path
     h
   end