The essence of the question is: Is it possible to use WAMP notifications in a Django application supporting both Python 2.7 and 3.4, considering that code should be running and only be interrupted if a Remote Procedure Call is made? (That is, it's not only waiting for a RPC to come)
How we want to use WAMP: the program has a Javascript frontend with a Python/Django backend. One of the things we do is start a function in the backend when a button in the frontend is clicked. This sometimes takes too much time though, so we allow the user to cancel that by clicking another button. This one makes a Remote Procedure Call, which will cause the function to stop earlier (it changes a variable that is checked in the function). There might be other needs for RPC or Pub/Sub in the future too.
We got it working with Python 2.7 using the autobahn_sync module, but it uses Twisted, which hasn't yet been fully ported to Python 3.x. That's why we would need another way of getting our WAMP notification to work on 3.x.
asyncio is supported and from the crossbar documentation it seemed it could be used instead of Twisted, but we can't get it to work without blocking the code that should be running in parallel (code is added below). And there doesn't seem to be something like autobahn_sync using asyncio instead of Twisted.
We're new to WAMP and there might be something we're missing.
Here's the code (with Python 3.4) we're testing using asyncio. It's blocking the rest of the function:
from asyncio import coroutine, new_event_loop, set_event_loop
from autobahn.asyncio.wamp import ApplicationSession, ApplicationRunner
class MyComponent(ApplicationSession):
@wamp.register("com.function.cancel")
def cancel(self):
print("called cancel procedure")
# do things here
return "Canceled"
@coroutine
def onJoin(self, details):
res = yield from self.register(self)
print("{} procedures registered.".format(len(res)))
def function_triggered_in_frontend():
loop = new_event_loop()
set_event_loop(loop)
runner = ApplicationRunner(url=u"ws://localhost:8080/ws", realm=u"realm1")
runner.run(MyComponent)
# and now the function should continue working on other things, but does't because it doesn't return from runner.run().
print("do stuff")
How can we register to the topic and return from the runner.run call? In the Python 2.7 test, with autobahn_sync we could simply do:
from autobahn_sync import register, run, AlreadyRunningError
@register('com.function.cancel')
def cancel_generate_jobs():
print("called cancel procedure")
@register('com.function.cancel')
# def cancel_generate_jobs():
def function_triggered_in_frontend():
try:
run(realm=u"realm1")
except AlreadyRunningError:
logger.info('AutbahnSync instance already started.')
# and then the code would continue being processed here, as we want