sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit 1c49911589cd00bf8b0b6160926e9cb5220ab2a3
parent 330291165aacbc25947bbb32d7661b0b1329d425
Author: wmorgan <wmorgan@5c8cc53c-5e98-4d25-b20a-d8db53a31250>
Date:   Tue,  2 Jan 2007 20:32:34 +0000

shared ssh connections if they're to the same username and host


git-svn-id: svn://rubyforge.org/var/svn/sup/trunk@139 5c8cc53c-5e98-4d25-b20a-d8db53a31250

Diffstat:
M lib/sup/mbox/ssh-file.rb | 45 ++++++++++++++++++++++++++++++++-------------
1 file changed, 32 insertions(+), 13 deletions(-)
diff --git a/lib/sup/mbox/ssh-file.rb b/lib/sup/mbox/ssh-file.rb
@@ -82,6 +82,9 @@ class SSHFile
   REASONABLE_TRANSFER_SIZE = 1024 * 32
   SIZE_CHECK_INTERVAL = 60 * 1 # seconds
 
+  @@shells = {}
+  @@shells_mutex = Mutex.new
+
   def initialize host, fn, ssh_opts={}
     @buf = Buffer.new
     @host = host
@@ -95,6 +98,7 @@ class SSHFile
 
   def broken?; !@broken_msg.nil?; end
 
+  ## TODO: share this code with imap
   def say s
     @say_id = BufferManager.say s, @say_id if BufferManager.instantiated?
     Redwood::log s
@@ -106,20 +110,35 @@ class SSHFile
   private :say, :shutup
 
   def connect
-    return if @session
     raise SSHFileError, @broken_msg if broken?
-
-    say "Opening SSH connection to #{@host}..."
-
-    begin
-      #raise SSHFileError, "simulated SSH file error"
-      @session = Net::SSH.start @host, @ssh_opts
-      say "Starting SSH shell..."
-      @shell = @session.shell.sync
-      say "Checking for #@fn..."
-      raise Errno::ENOENT, @fn unless @shell.test("-e #@fn").status == 0
-    ensure
-      shutup
+    return if @shell
+
+    key = [@host, @ssh_opts[:username]]
+    @shell = 
+      @@shells_mutex.synchronize do
+      if @@shells.member? key
+        returning(@@shells[key]) do |shell|
+          say "Checking for #@fn..."
+          begin
+            raise Errno::ENOENT, @fn unless shell.test("-e #@fn").status == 0
+          ensure
+            shutup
+          end
+        end
+      else
+        say "Opening SSH connection to #{@host}..."
+        begin
+          #raise SSHFileError, "simulated SSH file error"
+          session = Net::SSH.start @host, @ssh_opts
+          say "Starting SSH shell..."
+          shell = session.shell.sync
+          say "Checking for #@fn..."
+          raise Errno::ENOENT, @fn unless shell.test("-e #@fn").status == 0
+          @@shells[key] = shell
+        ensure
+          shutup
+        end
+      end
     end
   end