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

Provide gRPC read handle to the Oak entrypoint #874

Closed
ipetr0v opened this issue Apr 20, 2020 · 4 comments · Fixed by #993
Closed

Provide gRPC read handle to the Oak entrypoint #874

ipetr0v opened this issue Apr 20, 2020 · 4 comments · Fixed by #993
Assignees

Comments

@ipetr0v
Copy link
Contributor

ipetr0v commented Apr 20, 2020

Function that runs an event loop for a Node is called in the entrypoint (aka oak_main) created by this macro:

oak/sdk/rust/oak/src/lib.rs

Lines 567 to 576 in 6712ee6

pub extern "C" fn $name(in_handle: u64) {
// A panic in the Rust module code cannot safely pass through the FFI
// boundary, so catch any panics here and drop them.
// https://doc.rust-lang.org/nomicon/ffi.html#ffi-and-panics
let _ = ::std::panic::catch_unwind(|| {
::oak::set_panic_hook();
::oak::run_event_loop($node, in_handle);
});
}

This entrypoint requires an in_handle to receive messages, and this handle is provided by the Runtime upon creating this Node.
In the case of gRPC server pseudo-Node this in_handle is created during the pseudo-Node creation. But this pseudo-Node is created by the original Node with an entrypoint, that at this point has already been created and provided with an in_handle.
And this results in a loop.

We need to change a way of how the initial Node is created.
We have several possible options:

  • Node creates a gRPC server pseudo-Node, receives invocations from it, and dispatches them to the impl of the gRPC service, which is all in the same node.
  • Node creates a gRPC server pseudo-Node, and the gRPC service node (which will still be declared using the current entrypoint macro), then forwards invocations to that node.
  • Runtime creates two Nodes: a gRPC server pseudo-Node and the main Node (which uses a handle returned by the former). This approach is similar to the current approach used in the C++ Runtime.

Originated from a Slack thread: https://project-oak.slack.com/archives/CHE9E13C3/p1587068768173500

cc @tiziano88 @daviddrysdale

@ipetr0v ipetr0v self-assigned this Apr 20, 2020
@tiziano88
Copy link
Collaborator

My preference would be towards the second approach:

Node node creates a gRPC server pseudo-Node, and the gRPC service node (which will still be declared using the current entrypoint macro), then forwards invocations to that node.

Since it is more composable, and also plays better with IFC, especially when introducing per-user labels. For instance, this would make it easy for the "main" Node to act as a router based on the labels of individual gRPC invocations.

@ipetr0v
Copy link
Contributor Author

ipetr0v commented Apr 23, 2020

It might be possible to use a procedural macro just like tokio::main:

#[oak::main]
fn main(_: Handle) {
    let node = RunningAverageDispatcher::new(Node::default());
    let grpc_handle = oak::grpc::server::init();
    oak::run_event_loop(node, grpc_handle);
}

And it will be more convenient for developers since it will be just a regular main function.

@tiziano88
Copy link
Collaborator

procedural macros are a pain to maintain, we used to have them but we removed a while ago, I would avoid reintroducing them unless absolutely necessary

@ipetr0v
Copy link
Contributor Author

ipetr0v commented Apr 23, 2020

Then it may just be an already existing entrypoint, but it will not call an event loop by itself (so a developer will need to do this manually):

oak::entrypoint!(oak_main => {
    let node = RunningAverageDispatcher::new(Node::default());
    let grpc_handle = oak::grpc::server::init();
    oak::run_event_loop(node, grpc_handle);
})

This will allow a developer to choose which pseudo-Nodes to run and listen to (e.g. gRPC or HTTP) without introducing multiple new macros for each combination of pseudo-Nodes.

But it will hide an in_handle provided by the Runtime (not sure if we even need it).

@tiziano88 tiziano88 added the P1 label May 12, 2020
@ipetr0v ipetr0v added P0 and removed P1 labels May 13, 2020
ipetr0v added a commit that referenced this issue May 21, 2020
This change:
- Updates examples to use Rust Loader
- Updates macro and scripts for running Rust Loader
- Makes Oak CI to use Rust Loader for running examples
- Builds Rust Oak Loader with Cargo
- Fixes minor issues with gRPC server/client pseudo-Nodes

Fixes #725
Fixes #874
Fixes #901
Ref #945
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants