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

Reconnecting after a disconnect #272

Closed
Terrance opened this issue Nov 1, 2016 · 2 comments
Closed

Reconnecting after a disconnect #272

Terrance opened this issue Nov 1, 2016 · 2 comments

Comments

@Terrance
Copy link
Contributor

Terrance commented Nov 1, 2016

I'm attempting to write a long-running app with a Hangouts connection, so in the event of a disconnect I'd like to handle this quietly in the background. Currently I have something like the following:

client = hangups.Client(hangups.auth.get_auth_stdin("refresh_token.txt"))
loop = asyncio.get_event_loop()

def on_connect():
    # Some other initialisation stuff here.
    pass

def on_disconnect():
    try:
        loop.stop()
    except RuntimeError as e:
        # Couldn't stop the event loop?
        pass
    while loop.is_running():
        time.sleep(1)
    loop.run_until_complete(client.connect())

def run():
    client.on_connect.add_observer(on_connect)
    client.on_reconnect.add_observer(on_connect)
    client.on_disconnect.add_observer(on_disconnect)
    try:
        loop.run_until_complete(client.connect())
    except Exception as e:
        # Hangups exception?
        pass
    on_disconnect()

But on the second connect() call inside on_disconnect, I get:

ValueError: <function on_connect at 0x6ffffffffff> is already an observer of Event('Channel.on_connect')

Trying to restart a stopped event loop also gives errors like:

RuntimeError: Event loop stopped before Future completed.

This all feels rather messy -- I haven't used asyncio before so I'm not entirely sure if there's a better way to work with the event loop. Is there a correct way to handle reconnects?

@tdryer
Copy link
Owner

tdryer commented Nov 3, 2016

Client currently doesn't support connect being called more than once, so after a disconnect you will need to re-instantiate it.

I think to fix the event loop errors you have to do something like this:

task = asyncio.async(client.connect())
try:
    loop.run_until_complete(task)
except:
    task.cancel()
    loop.run_forever()
finally:
    loop.close()

@Terrance
Copy link
Contributor Author

Terrance commented Nov 3, 2016

I've now got it wrapped up like that, and it recreates the client when the event loop fails or the client disconnects. Seems to work! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants