Skip to content

rpc.call_async() without Future #12

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

Open
razvanphp opened this issue Oct 3, 2024 · 3 comments
Open

rpc.call_async() without Future #12

razvanphp opened this issue Oct 3, 2024 · 3 comments

Comments

@razvanphp
Copy link

razvanphp commented Oct 3, 2024

I am writing a dual-core app running on Portenta H7 with micropython on M7 + arduino code on M4.

My use-case for true paralelism is to call a function and never expect for the return value (since it's void anyway). I want to do this call in a non-blocking way, so I used rpc.call_async() but after 150 calls, I get this error:

timeout waiting for a free buffer
(OR)
memory allocation failed, allocating 4168 bytes

This does not happen with rpc.call(), but I do not want to introduce latency.

How can we achieve this?

Thanks!
R

@iabdalkader
Copy link
Collaborator

return value (since it's void anyway).

It's a request-response protocol; all requests return responses, even if the called function returns void, as defined by the protocol here: https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md#response-message

but after 150 calls, I get this error:

If you don't join future objects you will run out of memory eventually. All future objects must be joined at some point so they're collected and free'd. Async calls are also described in the protocol:
https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md#step-2-asynchronous-call

The library implements the protocol specs as closely as possible. If you want a different behavior you could try changing the code to discard async-responses, if they're not needed, but I don't think we want this as a feature.

@razvanphp
Copy link
Author

my intention is not to break the protocol specs, but to have a way to support this case as well, avoiding the memory fillup.

Any suggestion how can I clean up the Future objects, maybe doing self.msgbuf.pop() automatically as soon as a response is received? I think it would be useful for more people than us, it's not so uncommon to have a void function call.

Alternative to wait for the answer makes no sense for dual-cpu usage, as it will block the current thread during this time.

Thanks!
R

@iabdalkader
Copy link
Collaborator

I think it would be useful for more people than us, it's not so uncommon to have a void function call.

I think you're misunderstanding the response/return, even void functions can still fail (for example, if you call an unbound function). If you ignore the response, you'll have no way of detecting that.
Note that with join() you can use try..except around the join() call, handle the exception and continue, but if you raise an exception from the receive call you'll not be able to handle it.

maybe doing self.msgbuf.pop() automatically as soon as a response is received? I

I really can't think of an easy way to implement what you want, short of overhauling the library.

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