Re: [paramiko] Multithreading

2010-06-30 Thread Nikolaus Rath
On 06/30/2010 09:03 AM, Marcin Krol wrote:
 Nikolaus Rath wrote:
 Hello,

 I would like to use an SFTPClient instance concurrently with several
 threads, but I couldn't find any information about thread safety in the
 API documentation.

  - Can I just share the SFTPClient instance between several threads?
 
 Why use SFTPClient? Its performance might not be very good plus
 compatibility issues with some SSH servers might crop up. I know I had
 compatibility issues even with some pretty standard SSH servers on some
 platforms (esp. Solaris).
 
 I would avoid SFTPClient if I were you.
 
 I wrote my own multithreaded SCP class (handling both upload and
 download) which I can post if you're interested. It's been in use for a
 while by several users and I think it's pretty well debugged by now.


All I need is a Python API for uploading, downloading and renaming files
over SSH. I chose SFTPClient since it seemed to be the simplest
solution, and I don't remember seeing any warnings about performance or
compatibility. Can you tell me what exactly the problem with SFTPClient
is? Are there any better options within paramiko? In any case, I am
certainly interested in taking a look at your solution.


 There's quite a number of rather nasty problems you need to deal with:
 for instance, what if you need to close down the thread in the middle of
 operation but SFTPClient doesn't allow that? 

When I'm in the middle of an operation, then I am in the middle of an
SFTPClient method. Obviously I can't shut down the thread while the
interpreter is not executing my code. This doesn't seem to be an
SFTPClient or even multithreading specific problem to me.

 What if you're shutting
 down an interpreter and SFTPClient throws an exception which is visible
 for end user?

The interpreter should keep running while at least one thread is alive.
It seems to me that if SFTPClient throws an exception, obviously
something went wrong and it is a good think to know about it.


 What if there's no SCP/sftp on the other end (and this
 does happen from time to time) 

If the user tries to establish an SFTP connection to a server that does
not support SFTP, then things will obviously break. But that's not a bug
in the program.


 I have done quite a lot of work on
 getting my class to work reasonably under such circumstances: for
 instance, thread's file sending/downloading methods watch value of
 thread.abort flag and if it's set to True by an external class, they
 shut down gracefully.


I think you are using multithreading in a different way. Let me guess:
you have a main thread that has to stay responsive and therefore
delegates time-consuming operations to individual worker threads. These
worker threads must shut down when the main threads asks them to do so.
In this situation you have to deal with the problems you describe, but
they are not specific to SFTPClient and they do not always arise when
using multiple threads.

For example, my application is much simpler. I have several threads
which work independently of each other. There is no main controlling
thread. The application terminates when all the threads have finished
their work. (I am essentially programming a server with individual
threads handling client requests).



 Obviously, all the normal caveats about multithreading apply: 
 remembering to sleep just in case after releasing locks to prevent
 starvation

I never heard of that. Could you explain in more detail what you mean?



Best,

   -Nikolaus

-- 
 »Time flies like an arrow, fruit flies like a Banana.«

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6  02CF A9AD B7F8 AE4E 425C

___
paramiko mailing list
paramiko@lag.net
http://www.lag.net/cgi-bin/mailman/listinfo/paramiko

Re: [paramiko] Multithreading

2010-06-30 Thread Marcin Krol

Nikolaus Rath wrote:

All I need is a Python API for uploading, downloading and renaming files
over SSH. I chose SFTPClient since it seemed to be the simplest
solution, and I don't remember seeing any warnings about performance or
compatibility. 


I don't know about paramiko implementation of SFTPClient, but I tried 
using SFTP in my environment (lots of diverse operating systems) and it 
didn't work well really: sometimes it worked, sometimes it didn't, so I 
moved to SCP and haven't looked back. I didn't really investigate those 
problems with SFTP, just got discouraged by them.



Can you tell me what exactly the problem with SFTPClient
is? Are there any better options within paramiko? 


Simple SCP.



In any case, I am
certainly interested in taking a look at your solution.


Here:

class SSHThread(threading.Thread):
def __init__(self, hostip, user, passwd, sshprivkey, localpath, 
remotepath, action):


threading.Thread.__init__(self)

self.ip = hostip
self.username = user
self.passw = passwd
self.sshprivkey = sshprivkey
self.localpath = localpath
self.remotepath = remotepath
self.action = action
self.port = 22
self.finished = False
self.conerror = ''
self.confailed = False
self.abort = False
self.trans = None
self.sock = None
self.sentbytes = 0
self.socket_timeout = 30
self.result = ''

def run(self):
self.ssh_connect_for_scp()
if self.action == 'download' and not self.confailed:
self.download()
elif self.action == 'upload' and not self.confailed:
self.sendfilesrecursive()
elif self.action == 'listdir' and not self.confailed:
self.listdir()
try:
self.trans.close()
except AttributeError:
pass
self.finished = True

def _get_transport(self):
sock = socket.create_connection((self.ip,self.port), 
self.socket_timeout)

trans = paramiko.Transport(sock)
ciphers = trans.get_security_options()._get_ciphers()
if 'blowfish-cbc' in ciphers:
ciphers = ('blowfish-cbc',) + ciphers
if 'arcfour128' in ciphers:
ciphers = ('arcfour128',) + ciphers
trans.get_security_options().ciphers = ciphers
self.sock = sock
self.trans = trans
self.trans.set_log_channel('adserver')

def printandclose(self):
print \ntrying to close transport.sock
#self.trans.close()
self.trans.sock.close()
self.flag = True

def ssh_connect_for_scp(self):
loginsuccess = False
try:
self._get_transport()
except Exception, e:
self.conerror = str(e)
self.confailed = True
self.finished = True
return
# password
if self.passw:
try:
#timer = threading.Timer(4, self.printandclose)
#timer.start()
self.trans.connect(hostkey=None, 
username=self.username, password=self.passw, pkey=None)

#self.trans.start_client()
#timer.cancel()
loginsuccess = True
except Exception, e:
self.conerror = str(e)
# key file
pkey = None
if not loginsuccess and self.sshprivkey:
try:
pkey = 
paramiko.RSAKey.from_private_key_file(self.sshprivkey)

except paramiko.SSHException:
try:
pkey = 
paramiko.DSSKey.from_private_key_file(self.sshprivkey)

except paramiko.SSHException:
pass
except IOError, e:
self.conerror = str(e)
self.finished = True
self.confailed = True
return
if pkey:
try:
#self.conobj.connect(self.ip, 
username=self.username, key_filename=self.sshprivkey, port=self.port, 
timeout=opts.timeout)

self._get_transport()
self.trans.connect(hostkey=None, 
username=self.username, pkey = pkey)

loginsuccess = True
self.conerror = ''
except Exception, e:
self.conerror = str(e)
# agent
#if not loginsuccess:
#agent = paramiko.Agent()
#ak = agent.get_keys()
#for key in ak:
#try:
#self._get_transport()
#self.trans.connect(hostkey=None, 
username=self.username, pkey = key )

#loginsuccess = True
#self.conerror = ''
#break
#except Exception, e:
#self.conerror = str(e)

if not loginsuccess:
self.confailed = True
self.conobj = None
self.finished = 

Re: [paramiko] Multithreading

2010-06-30 Thread james bardin
On Wed, Jun 30, 2010 at 11:13 AM, Marcin Krol mrk...@gmail.com wrote:

 Obviously, all the normal caveats about multithreading apply: remembering
 to sleep just in case after releasing locks to prevent
 starvation

 I never heard of that. Could you explain in more detail what you mean?

 http://linuxgazette.net/107/pai.html

 Caveat: I don't know if this has been improved in Python thread handling
 since that article has been written, but I add a bit of sleeping after lock
 release anyway just to be safe.


That's a poor example of python coding. It's highlighting a GIL issue,
but if you have that sort of contention, you shouldn't be using
multiple threads. The author may have encountered a problem, but he
didn't fully understand it, or his own solution; which is why adding a
magic sleep seems to work. Note that you will get slightly different
results on a multicore system.

The main loop is a busy loop! It's hogging the GIL itself, and pegging
a cpu core at %100.
Because the threads only do work with a lock, there is no time for the
GIL to switch threads., The sleep() simply allows a few cycles for the
GIL to be released.


-jim

___
paramiko mailing list
paramiko@lag.net
http://www.lag.net/cgi-bin/mailman/listinfo/paramiko


Re: [paramiko] Multithreading

2010-06-30 Thread Nikolaus Rath
james bardin jbar...@bu.edu writes:
 On Wed, Jun 30, 2010 at 9:33 AM, Nikolaus Rath nikol...@rath.org wrote:
 Nikolaus Rath wrote:
 Hello,

 I would like to use an SFTPClient instance concurrently with several
 threads, but I couldn't find any information about thread safety in the
 API documentation.

  - Can I just share the SFTPClient instance between several threads?


 Yes. Though you may have a use case, there's no performance benefit,
 as the client can only handle one operation at a time.

I am mostly concerned about reducing the network latency. Suppose I want
to create 100 1-bit files, then I hope that it is going to be faster to
send 100 requests at once from 100 threads rather than having one thread
that works through the files sequentially. That should still work even
with a single threaded client, right?

 Why use SFTPClient? Its performance might not be very good plus
 compatibility issues with some SSH servers might crop up. I know I had
 compatibility issues even with some pretty standard SSH servers on some
 platforms (esp. Solaris).


 There are throughput performance issues with older ssh servers that
 don't support prefetch and pipelining.

Ah, so the problem is with the server and not with the SFTPClient class?
My servers are given and only speak SFTP, so I am to live with them in
any case.


Best,

   -Nikolaus

-- 
 »Time flies like an arrow, fruit flies like a Banana.«

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6  02CF A9AD B7F8 AE4E 425C

___
paramiko mailing list
paramiko@lag.net
http://www.lag.net/cgi-bin/mailman/listinfo/paramiko