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

Non-blocking requests #91

Open
loyd opened this issue Jun 2, 2023 · 4 comments
Open

Non-blocking requests #91

loyd opened this issue Jun 2, 2023 · 4 comments
Milestone

Comments

@loyd
Copy link
Collaborator

loyd commented Jun 2, 2023

API for non-blocking requests.

Something like this:

#[message(ret = u32)]
struct SomeRequest(u32);

let request_map = RequestMap::new(); // `SecondaryMap` underhood
let request_id = ctx.request(SomeRequest(42)).id().await;

// Store additional information
request_map.insert(request_id, SomeInfo { name: "kek" });

while let Some(envelope) = ctx.recv().await {
    msg!(match envelope {
        SomeRequest::Response(request_id, ret) => {
            let info = request_map.take(request_id);
            info!(message = "got it", name = %info.name, ret = %ret);
        }
        SomeRequest::Error(err) => { .. }
    });
}

For the receiving part, nothing is changed.

@loyd loyd added this to the v0.2 milestone Jun 2, 2023
@planetoryd
Copy link

It's possible to deadlock. Amiright

@loyd
Copy link
Collaborator Author

loyd commented Sep 27, 2023

What kind of deadlock do you see here?

I'm always planning to handle responses unboundedly (so ctx.respond(token) is non-blocking already), so I don't see where deadlock can occur for now.

Compared to blocking requests (ctx.request(..).resolve().await), where there is a case with two actors requesting each other, the non-blocking variant has no such problem.

@planetoryd
Copy link

If one actor requests another actor (send message1, wait for response1), and the other actor requests back in the method, (send message2, wait for response2, send response1). It forms a wait-for cycle, message2 is never processed because the first actor is still in the process of requesting. I'm not sure how you implement it, but it's easy to happen.

@loyd
Copy link
Collaborator Author

loyd commented Sep 27, 2023

Yep, it's a case for blocking requests (ctx.request(..).resolve().await). But in the case of non-blocking requests, all responses are handled using a mailbox in the typical main loop, so there is no point when both actors wait for each other, thus requests can overlap.

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