[Python] How to properly terminate in all cases when using the new component API

31 views
Skip to first unread message

Armin Berres

unread,
Aug 3, 2018, 11:22:12 AM8/3/18
to Autobahn
Hi,

I am evaluating the new component based Python API.

There is one thing I cannot find a proper solution for: Reliably and cleanly termination.

I see three cases right now:
 1) Terminating at random time when a session is open
 2) Terminating at random time without open session
 3) Terminating in on_leave when detecting that reconnecting does not make sense.

Case 1) seems relatively easy.
Cleanup whatever needs to be cleaned up and then call session.leave().
Open question: How to handle the case where one wants to leave the session but execute some coroutines later on for cleanup?

Case 2 and 3)
I do not see a way to stop the running component from reconnecting apart from calling asyncio.get_event_loop().stop().
That is no real solution though.

To illustrate the cases I attach a short program showing the cases.
It either tries to terminate when authentication failed or it terminates after 10 seconds.
Depending on the state of the connection this can trigger all cases above.

Has anyone an idea how to handle these cases?

One can pass a 'main' method to the component. It will only terminate once this method is done.
The only problem: The method is bound to a joined session. Does not seem to help in my case.
Binding the component to a constantly running methos (like the run method in the sample code) would maybe help.

Cheers,
Armin
termination_test.py

Zaar Hai

unread,
Oct 25, 2018, 1:46:34 AM10/25/18
to Autobahn
Hi Armin,

Can't fetch the attachment for some reason.
Component access is_fatal callback which controls whether another connection attempt should be attempted.

I use the following, for example, to check that anonymous access is disabled:

import asynctest
import structlog

from autobahn.asyncio.component import Component
from autobahn.wamp import exception as wexc

class TestChanneler(asynctest.TestCase):

    # This is a workaround :(
    use_default_loop = True
    
    async def test_01_no_anonymous(self):

        errs = [None]

        component = Component(
            main=main,
            is_fatal=lambda exc: True,
        )   
        
        @component.on_leave
        def on_leave(session, close_details):
            errs[0] = close_details.reason
            
        with self.assertRaises(RuntimeError):
            await component.start(loop=self.loop)
        self.assertIn(wexc.ApplicationError.NO_AUTH_METHOD, errs)
Reply all
Reply to author
Forward
0 new messages