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

fix(client): enter tokio runtime context before calling timeout in recv_timeout #492

Merged
merged 2 commits into from
Nov 1, 2022

Conversation

swanandx
Copy link
Member

timeout function uses Sleep internally, but as we are outside of Tokio runtime context, it will fail to spawn it and thus will panic! reference.

To fix it, we can explicitly enter the runtime by using enter method.

Fixes Issue: #467

@tekjar tekjar merged commit 3878642 into main Nov 1, 2022
@swanandx swanandx deleted the fix-recv-timeout branch November 8, 2022 16:54
@@ -427,6 +427,9 @@ impl Connection {
&mut self,
duration: Duration,
) -> Result<Result<Event, ConnectionError>, RecvTimeoutError> {
// Enter the runtime so we can use Sleep, which is required by timeout.
// ref: https://docs.rs/tokio/latest/tokio/runtime/struct.Runtime.html#method.enter
let _guard = self.runtime.enter();
Copy link
Contributor

@de-sh de-sh Nov 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seem like this could have been fixed by ensuring the construction of the timeout happened within an async block passed to block_on without having to explicitly enter the runtime context. Have tested and verified its working.

.block_on(async { timeout(duration, f).await })

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did try it out, but for me it didn't work. That is why I ended up choosing the solution of manually entering runtime.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe since the timeout would be created outside the runtime context before being passed into block_on(), the reactor would be deemed missing whereas within async { } the timeout is only created once the external future gets polled from within the runtime.

Thus why .block_on(timeout(duration, f)) behaves different to .block_on(async { timeout(duration, f).await }).

Copy link
Member Author

@swanandx swanandx Nov 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah you are right, I was creating timeout future first and then passing it down in that async block inside block_on 😅. Good catch! If entering guard isn't required, can we remove it in your PR?

carlocorradini pushed a commit to carlocorradini/rumqtt that referenced this pull request Aug 3, 2023
…cv_timeout (bytebeamio#492)

* fix: recv_timeout

* updated changes in changelog
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

Successfully merging this pull request may close these issues.

3 participants