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

feat: extract next runtime into separate binary #679

Merged
merged 2 commits into from
Mar 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion cargo-shuttle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,6 @@ impl Shuttle {

let start_request = StartRequest {
deployment_id: id.as_bytes().to_vec(),
service_name,
ip: addr.to_string(),
};

Expand Down
8 changes: 1 addition & 7 deletions deployer/src/deployment/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,6 @@ impl Built {
.unwrap();
run(
self.id,
self.service_name,
runtime_client,
address,
deployment_updater,
Expand Down Expand Up @@ -280,7 +279,6 @@ async fn load(
#[instrument(skip(runtime_client, deployment_updater, kill_recv, cleanup), fields(state = %State::Running))]
async fn run(
id: Uuid,
service_name: String,
runtime_client: &mut RuntimeClient<Channel>,
address: SocketAddr,
deployment_updater: impl DeploymentUpdater,
Expand All @@ -294,7 +292,6 @@ async fn run(

let start_request = tonic::Request::new(StartRequest {
deployment_id: id.as_bytes().to_vec(),
service_name: service_name.clone(),
ip: address.to_string(),
});

Expand All @@ -310,10 +307,7 @@ async fn run(

while let Ok(kill_id) = kill_recv.recv().await {
if kill_id == id {
let stop_request = tonic::Request::new(StopRequest {
deployment_id: id.as_bytes().to_vec(),
service_name: service_name.clone(),
});
let stop_request = tonic::Request::new(StopRequest {});
response = runtime_client.stop(stop_request).await;

break;
Expand Down
6 changes: 5 additions & 1 deletion runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ publish = false
[[bin]]
name = "rocket"

[[bin]]
name = "next"

[dependencies]
anyhow = { workspace = true }
async-trait = { workspace = true }
Expand All @@ -23,6 +26,7 @@ tonic = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] }
uuid = { workspace = true, features = ["v4"] }
# TODO: bump these crates to 6.0 when we bump rust to >= 1.66
oddgrd marked this conversation as resolved.
Show resolved Hide resolved
wasi-common = "4.0.0"
wasmtime = "4.0.0"
wasmtime-wasi = "4.0.0"
Expand All @@ -35,7 +39,7 @@ rocket = "0.5.0-rc.2"

[dependencies.shuttle-common]
workspace = true
features = ["wasm"]
features = ["wasm", "service"]

[dependencies.shuttle-proto]
workspace = true
Expand Down
4 changes: 2 additions & 2 deletions runtime/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
all: axum

axum:
cd ../tmp/axum-wasm-expanded; cargo build --target wasm32-wasi
cp ../tmp/axum-wasm-expanded/target/wasm32-wasi/debug/shuttle_axum_expanded.wasm axum.wasm
cd tests/resources/axum-wasm-expanded; cargo build --target wasm32-wasi
cp tests/resources/axum-wasm-expanded/target/wasm32-wasi/debug/shuttle_axum_expanded.wasm axum.wasm

test: axum
cargo test --all-features -- --nocapture
Expand Down
21 changes: 12 additions & 9 deletions runtime/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ make test
Load and run:

```bash
cargo run -- --axum --provisioner-address http://localhost:5000
cargo run --bin next -- --port 6001
```

In another terminal:
Expand All @@ -40,24 +40,27 @@ In another terminal:
grpcurl -plaintext -import-path ../proto -proto runtime.proto -d '{"service_name": "Tonic", "path": "/home/<path to shuttle>/runtime/axum.wasm"}' localhost:6001 runtime.Runtime/Load

# start
grpcurl -plaintext -import-path ../proto -proto runtime.proto -d '{"service_name": "Tonic", "deployment_id": "MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAw"}' localhost:6001 runtime.Runtime/Start
grpcurl -plaintext -import-path ../proto -proto runtime.proto -d '{"deployment_id": "MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAw", "ip": "127.0.0.1:8000"}' localhost:6001 runtime.Runtime/Start

# subscribe to logs (unimplemented)
# subscribe to logs
grpcurl -plaintext -import-path ../proto -proto runtime.proto localhost:6001 runtime.Runtime/SubscribeLogs

# stop
grpcurl -plaintext -import-path ../proto -proto runtime.proto -d '{"service_name": "Tonic", "deployment_id": "MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAw"}' localhost:6001 runtime.Runtime/Stop
grpcurl -plaintext -import-path ../proto -proto runtime.proto -d '{}' localhost:6001 runtime.Runtime/Stop
```

Curl the service:
```bash
curl localhost:7002/hello
curl localhost:8000/hello

curl localhost:7002/goodbye
curl localhost:8000/goodbye
```

## shuttle-legacy
This will no loger load a `.so` will the code to start the runtime will be codegened for all services.

This will no longer load a `.so` file, the code to start the runtime will be
codegened for all services.

An example can be found in `src/bin/rocket.rs` which contains the secrets rocket example at the bottom and the codegen at the top.

To test, first start a provisioner from the root directory using:
Expand All @@ -69,7 +72,7 @@ docker-compose -f docker-compose.rendered.yml up provisioner
Then in another shell, start the wrapped runtime using the clap CLI:

```bash
cargo run -- --port 6001 --storage-manager-type working-dir --storage-manager-path ./
cargo run --bin rocket -- --port 6001 --storage-manager-type working-dir --storage-manager-path ./
```

Or directly (this is the path hardcoded in `deployer::start`):
Expand All @@ -87,7 +90,7 @@ Then in another shell, load the service and start it up:
grpcurl -plaintext -import-path ../proto -proto runtime.proto -d '{"service_name": "Tonic", "path": "/home/<path to shuttle>/examples/rocket/hello-world/target/debug/libhello_world.so", "secrets": {"MY_API_KEY": "test"}}' localhost:6001 runtime.Runtime/Load

# run (this deployment id is default uuid encoded as base64)
grpcurl -plaintext -import-path ../proto -proto runtime.proto -d '{"service_name": "Tonic", "deployment_id": "MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAw", "ip": "127.0.0.1:8000"}' localhost:6001 runtime.Runtime/Start
grpcurl -plaintext -import-path ../proto -proto runtime.proto -d '{"deployment_id": "MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAw", "ip": "127.0.0.1:8000"}' localhost:6001 runtime.Runtime/Start

# subscribe to logs
grpcurl -plaintext -import-path ../proto -proto runtime.proto localhost:6001 runtime.Runtime/SubscribeLogs
Expand Down
40 changes: 40 additions & 0 deletions runtime/src/bin/next.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use std::{
net::{Ipv4Addr, SocketAddr},
time::Duration,
};

use clap::Parser;
use shuttle_proto::runtime::runtime_server::RuntimeServer;
use shuttle_runtime::{AxumWasm, NextArgs};
use tonic::transport::Server;
use tracing::trace;
use tracing_subscriber::{fmt, prelude::*, EnvFilter};

#[tokio::main(flavor = "multi_thread")]
async fn main() {
let args = NextArgs::parse();

// TODO: replace with tracing helper from main branch
let fmt_layer = fmt::layer();
let filter_layer = EnvFilter::try_from_default_env()
.or_else(|_| EnvFilter::try_new("info"))
.unwrap();

tracing_subscriber::registry()
.with(filter_layer)
.with(fmt_layer)
.init();

trace!(args = ?args, "parsed args");

let addr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), args.port);

let mut server_builder =
Server::builder().http2_keepalive_interval(Some(Duration::from_secs(60)));

let axum = AxumWasm::default();
let svc = RuntimeServer::new(axum);
let router = server_builder.add_service(svc);

router.serve(addr).await.unwrap();
}
8 changes: 0 additions & 8 deletions runtime/src/args.rs → runtime/src/legacy/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,6 @@ pub struct Args {
#[arg(long, default_value = "http://localhost:5000")]
pub provisioner_address: Endpoint,

/// Is this runtime for a legacy service
#[arg(long, conflicts_with("axum"))]
pub legacy: bool,

/// Is this runtime for an axum-wasm service
#[arg(long, conflicts_with("legacy"))]
pub axum: bool,

/// Type of storage manager to start
#[arg(long, value_enum)]
pub storage_manager_type: StorageManagerType,
Expand Down
6 changes: 5 additions & 1 deletion runtime/src/legacy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ use tonic::{
use tracing::{error, instrument, trace};
use uuid::Uuid;

use crate::{provisioner_factory::ProvisionerFactory, Args};
use crate::provisioner_factory::ProvisionerFactory;

use self::args::Args;

mod args;

pub async fn start(
loader: impl Loader<ProvisionerFactory<WorkingDirStorageManager>> + Send + 'static,
Expand Down
7 changes: 3 additions & 4 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
mod args;
mod axum;
mod legacy;
mod next;
mod provisioner_factory;

pub use args::{Args, StorageManagerType};
pub use axum::AxumWasm;
pub use legacy::{start, Legacy};
pub use next::AxumWasm;
pub use next::NextArgs;
pub use provisioner_factory::ProvisionerFactory;
66 changes: 0 additions & 66 deletions runtime/src/main.rs

This file was deleted.

9 changes: 9 additions & 0 deletions runtime/src/next/args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use clap::Parser;

#[derive(Parser, Debug)]
#[command(version)]
pub struct NextArgs {
/// Port to start runtime on
#[arg(long)]
pub port: u16,
}
8 changes: 5 additions & 3 deletions runtime/src/axum/mod.rs → runtime/src/next/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ use wasmtime::{Engine, Linker, Module, Store};
use wasmtime_wasi::sync::net::UnixStream as WasiUnixStream;
use wasmtime_wasi::{WasiCtx, WasiCtxBuilder};

mod args;

pub use self::args::NextArgs;

extern crate rmp_serde as rmps;

const LOGS_FD: u32 = 20;
Expand Down Expand Up @@ -94,9 +98,7 @@ impl Runtime for AxumWasm {
&self,
request: tonic::Request<StartRequest>,
) -> Result<tonic::Response<StartResponse>, Status> {
let StartRequest {
deployment_id, ip, ..
} = request.into_inner();
let StartRequest { deployment_id, ip } = request.into_inner();

let address = SocketAddr::from_str(&ip)
.context("invalid socket address")
Expand Down