Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script won't exit because paramiko thread is still running #72

Closed
jsheedy opened this issue Sep 10, 2016 · 16 comments
Closed

Script won't exit because paramiko thread is still running #72

jsheedy opened this issue Sep 10, 2016 · 16 comments
Labels
Milestone

Comments

@jsheedy
Copy link

jsheedy commented Sep 10, 2016

The following script works and "FINISH" is printed, but it never exits to the shell:

import threading

from sshtunnel import SSHTunnelForwarder

with SSHTunnelForwarder(
    "localhost",
    ssh_username="localuser",
    ssh_password="localpass",
    remote_bind_address=('127.0.0.1', 5984),
    local_bind_address=('127.0.0.1', 9000)
) as server:

    print(server.local_bind_port)
    # these don't help
    # server.stop()
    # server.close()

# [t.close() for t in threading.enumerate() if t.__class__.__name__ == "Transport"]

print('FINISH!')

Python is waiting on threads to finish, but they never do. After running this script in iPython I can see the threads:

threading.enumerate()
[<_MainThread(MainThread, started 140735243972608)>,
 <HistorySavingThread(IPythonHistorySavingThread, started 123145307557888)>,
 <paramiko.Transport at 0x3880470 (cipher aes128-ctr, 128 bits) (connected; awaiting auth)>,
 <paramiko.Transport at 0x3874630 (cipher aes128-ctr, 128 bits) (connected; awaiting auth)>,
 <paramiko.Transport at 0x3191ba8 (cipher aes128-ctr, 128 bits) (connected; awaiting auth)>,
 <paramiko.Transport at 0x3874550 (cipher aes128-ctr, 128 bits) (active; 0 open channel(s))>,
 <paramiko.Transport at 0x3191c88 (cipher aes128-ctr, 128 bits) (connected; awaiting auth)>,
 <paramiko.Transport at 0x387bac8 (cipher aes128-ctr, 128 bits) (connected; awaiting auth)>,
 <paramiko.Transport at 0x3803e48 (cipher aes128-ctr, 128 bits) (connected; awaiting auth)>,
 <paramiko.Transport at 0x3874f60 (cipher aes128-ctr, 128 bits) (connected; awaiting auth)>]

If I uncomment the last line which explicitly closes the paramiko.Transport threads, the script exits correctly. It seems like I'm missing something, but even so this default behavior is confusing.

@fernandezcuesta
Copy link
Collaborator

fernandezcuesta commented Sep 10, 2016

Thanks for reporting, will have a look shortly.
Which version are you using BTW?

@jsheedy
Copy link
Author

jsheedy commented Sep 11, 2016

Thanks for looking into it! I just installed with pip. It got sshtunnel-0.1.0, paramiko-2.0.2, and pyasn1-0.1.9.

@fernandezcuesta
Copy link
Collaborator

Hi, could you please install from source (v0.1.0 branch) and retry?
Thx!

@jsheedy
Copy link
Author

jsheedy commented Sep 20, 2016

I tried installing the v0.1.0 branch and it is exiting correctly now. Thank you!

@nmz787
Copy link

nmz787 commented Mar 14, 2018

I am using 0.1.3 and if I try using sshtunnel from an interactive prompt, then exiting with CTRL-D, my session never closes. But if I explicitly call stop() then CTRL-D my session exits immediately. I tried using atexit but it didn't work for me. I also tried setting sshtunnel.DAEMON=True but that also didn't help.

@kylepolich
Copy link

Any fix for this?

@theoaf
Copy link

theoaf commented Sep 25, 2019

Experiencing the same problem

@bmetea
Copy link

bmetea commented Oct 24, 2019

I'm experiencing this too, any fix?

1 similar comment
@hshe
Copy link

hshe commented Dec 17, 2019

I'm experiencing this too, any fix?

@stobra
Copy link

stobra commented Jan 10, 2020

I was able to close the the connection after setting daemon_forward_servers = True

ssh_server = SSHTunnelForwarder(
        ssh_address_or_host= '98.123.89.123',
        ssh_username= 'name',
        ssh_pkey=pkey,
        remote_bind_address=(hostname, 1234))
ssh_server.daemon_forward_servers = True

with ssh_server as ssh:
        ssh.start()
        local_port = str(ssh.local_bind_port)
        conn = create_engine(f'mysql+pymysql://mysqldatabase:{local_port}')

@eykamp
Copy link

eykamp commented Jan 11, 2020

@stobra Thank you! When I set things up exactly this way they worked. Even a small deviation resulted in the hanging problem.

@dem82
Copy link

dem82 commented Jun 12, 2020

@stobra Thank you! I've solved the hanging problem with your suggestion

@stobra
Copy link

stobra commented Jun 13, 2020

@dem82, I'm glad to hear it was helpful. Best wishes

@franz101
Copy link

franz101 commented Jul 1, 2020

@stobra you sir are a legend!

@mwharton3
Copy link

Worked for me too, thank you so much!

@pahaz
Copy link
Owner

pahaz commented Nov 16, 2020

Because someone still finds this issue through a search I'll write it here:

  1. sshtunnel is always waiting until closing all connections during the stop() called.
  2. If you don't want to wait, you can use .stop(force=True)
  3. You can have a problem with hangs if you don't call .stop. For example, you have some unhandled exception in MainThread and you don't call .stop in this case. As a dirty workaround, you can use this hack at the beginning:
# I don't recommend to use this hack!
# Hack threadings https://docs.python.org/3/library/threading.html#threading.Thread.daemon ...
sshtunnel.SSHTunnelForwarder.daemon_forward_servers = True
sshtunnel.SSHTunnelForwarder.daemon_transport = True
  1. It's better to use with open_tunnel(...) which always stops the tunnel.

Please, don't leave a comment here. If you have any issues and still have any issues feel free to open a new one!

@pahaz pahaz added this to the 0.3.0 milestone Nov 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests