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

Reference to asyncio in synchronous method gmqtt.client.Client.publish #46

Closed
rkrell opened this issue Jun 6, 2019 · 6 comments
Closed

Comments

@rkrell
Copy link
Contributor

rkrell commented Jun 6, 2019

There is a wrong line in the publish() method of the client:

loop = asyncio.get_event_loop()

which causes failures in my code:

2019-06-06 10:26:48,687 [ERROR] connectors.printer_input: Traceback (most recent call last):
...
  File "/home/rkrell/work/project/site-packages/syncasync.py", line 120, in thread_handler
    return self.func(*args, **kwargs)
  File "/home/rkrell/work/project/site-packages/gmqtt/client.py", line 195, in publish
    loop = asyncio.get_event_loop()
  File "/home/rkrell/work/project/pypy3.5-7.0.0-linux_x86_64-portable/lib-python/3/asyncio/events.py", line 671, in get_event_loop
    return get_event_loop_policy().get_event_loop()
  File "/home/rkrell/work/project/pypy3.5-7.0.0-linux_x86_64-portable/lib-python/3/asyncio/events.py", line 583, in get_event_loop
    % threading.current_thread().name)
RuntimeError: There is no current event loop in thread 'Thread-1'.

Since this line has no effect it should be removed from this synchronous function.

@rkrell rkrell changed the title Reference to asyncio in synchronous method MQTTClient.publish Reference to asyncio in synchronous method gmqtt.client.Client.publish Jun 6, 2019
@rkrell
Copy link
Contributor Author

rkrell commented Jun 6, 2019

Thanks for merging, the above traceback does no longer occur now.

Would appreciate a release just in case of some spare time ;-) Thank you in advance

@rkrell rkrell closed this as completed Jun 6, 2019
@Mixser
Copy link
Contributor

Mixser commented Jun 6, 2019

@rkrell

Thanks for notice. As I can see, you are using threads (and pypy) and we didn't tested our lib in such way of usage.

May be the asyncio.set_event_loop method will be useful for you cases. I mean you need to connect the event loop to your threads before using the async methods in it.

If you did it and the problem still happening, notify us.

And thanks for your PR. 😊

@rkrell
Copy link
Contributor Author

rkrell commented Jun 6, 2019

The async_to_sync wrapper is just a workaround, because I need to call async methods from within the gmqtt callbacks. Best would be having coroutines as callbacks, that would simplify it a lot.

Thank you all for acting so fast.

@Mixser
Copy link
Contributor

Mixser commented Jun 6, 2019

Hi,

We support an async callback only for on_message. May be it will help you.

Also you always can add coroutine to event loop from sync method in this way:

async def example(*args, **kwargs):
    # do async stuff
    pass

def on_message(*args, **kwargs):
    asyncio.ensure_future(example(*args, **kwargs)

@rkrell
Copy link
Contributor Author

rkrell commented Jun 6, 2019

Aha, I see now:

gmqtt/gmqtt/mqtt/handler.py

Lines 296 to 299 in d198e5b

if iscoroutinefunction(self.on_message):
asyncio.ensure_future(self.on_message(self, print_topic, packet, qos, properties))
else:
self.on_message(self, print_topic, packet, qos, properties)

Very good solution, to be able to use sync and async according to the needs.
This will help much avoiding workarounds. Thanks.

@rkrell
Copy link
Contributor Author

rkrell commented Jun 6, 2019

Also you always can add coroutine to event loop from sync method in this way:

async def example(*args, **kwargs):
    # do async stuff
    pass

def on_message(*args, **kwargs):
    asyncio.ensure_future(example(*args, **kwargs)

Good point, will try this.

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

No branches or pull requests

2 participants