forked from ROMEO/nexosim
Simplify gRPC backend arch + remove wasm backend
This commit is contained in:
parent
3ccf05335b
commit
6b43fcf704
16
.github/workflows/ci.yml
vendored
16
.github/workflows/ci.yml
vendored
@ -28,7 +28,7 @@ jobs:
|
|||||||
toolchain: ${{ matrix.rust }}
|
toolchain: ${{ matrix.rust }}
|
||||||
|
|
||||||
- name: Run cargo check
|
- name: Run cargo check
|
||||||
run: cargo check --features="grpc-service"
|
run: cargo check --all-features
|
||||||
|
|
||||||
build-wasm:
|
build-wasm:
|
||||||
name: Build wasm32
|
name: Build wasm32
|
||||||
@ -43,7 +43,7 @@ jobs:
|
|||||||
targets: wasm32-unknown-unknown
|
targets: wasm32-unknown-unknown
|
||||||
|
|
||||||
- name: Run cargo build (wasm)
|
- name: Run cargo build (wasm)
|
||||||
run: cargo build --target wasm32-unknown-unknown --features="wasm-service"
|
run: cargo build --target wasm32-unknown-unknown
|
||||||
|
|
||||||
test:
|
test:
|
||||||
name: Test suite
|
name: Test suite
|
||||||
@ -56,7 +56,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@stable
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
|
||||||
- name: Run cargo test
|
- name: Run cargo test
|
||||||
run: cargo test --features="grpc-service"
|
run: cargo test --all-features
|
||||||
|
|
||||||
loom-dry-run:
|
loom-dry-run:
|
||||||
name: Loom dry run
|
name: Loom dry run
|
||||||
@ -69,7 +69,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@stable
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
|
||||||
- name: Dry-run cargo test (Loom)
|
- name: Dry-run cargo test (Loom)
|
||||||
run: cargo test --no-run --tests --features="grpc-service"
|
run: cargo test --no-run --tests --all-features
|
||||||
env:
|
env:
|
||||||
RUSTFLAGS: --cfg asynchronix_loom
|
RUSTFLAGS: --cfg asynchronix_loom
|
||||||
|
|
||||||
@ -86,12 +86,12 @@ jobs:
|
|||||||
components: miri
|
components: miri
|
||||||
|
|
||||||
- name: Run cargo miri tests (single-threaded executor)
|
- name: Run cargo miri tests (single-threaded executor)
|
||||||
run: cargo miri test --tests --lib --features="grpc-service"
|
run: cargo miri test --tests --lib --all-features
|
||||||
env:
|
env:
|
||||||
MIRIFLAGS: -Zmiri-strict-provenance -Zmiri-disable-isolation -Zmiri-num-cpus=1
|
MIRIFLAGS: -Zmiri-strict-provenance -Zmiri-disable-isolation -Zmiri-num-cpus=1
|
||||||
|
|
||||||
- name: Run cargo miri tests (multi-threaded executor)
|
- name: Run cargo miri tests (multi-threaded executor)
|
||||||
run: cargo miri test --tests --lib --features="grpc-service"
|
run: cargo miri test --tests --lib --all-features
|
||||||
env:
|
env:
|
||||||
MIRIFLAGS: -Zmiri-strict-provenance -Zmiri-disable-isolation -Zmiri-num-cpus=4
|
MIRIFLAGS: -Zmiri-strict-provenance -Zmiri-disable-isolation -Zmiri-num-cpus=4
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ jobs:
|
|||||||
run: cargo fmt --all -- --check
|
run: cargo fmt --all -- --check
|
||||||
|
|
||||||
- name: Run cargo clippy
|
- name: Run cargo clippy
|
||||||
run: cargo clippy --features="grpc-service"
|
run: cargo clippy --all-features
|
||||||
|
|
||||||
docs:
|
docs:
|
||||||
name: Docs
|
name: Docs
|
||||||
@ -162,4 +162,4 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@stable
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
|
||||||
- name: Run cargo doc
|
- name: Run cargo doc
|
||||||
run: cargo doc --no-deps --features="grpc-service" --document-private-items
|
run: cargo doc --no-deps --all-features --document-private-items
|
||||||
|
@ -20,21 +20,12 @@ categories = ["simulation", "aerospace", "science"]
|
|||||||
keywords = ["simulation", "discrete-event", "systems", "cyberphysical", "real-time"]
|
keywords = ["simulation", "discrete-event", "systems", "cyberphysical", "real-time"]
|
||||||
autotests = false
|
autotests = false
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# Remote procedure call API.
|
|
||||||
rpc = ["dep:ciborium", "dep:serde", "dep:tonic", "dep:prost", "dep:prost-types", "dep:bytes"]
|
|
||||||
# This feature forces protobuf/gRPC code (re-)generation.
|
|
||||||
rpc-codegen = ["dep:tonic-build"]
|
|
||||||
# gRPC service.
|
# gRPC service.
|
||||||
grpc-service = ["rpc", "dep:tokio" , "tonic/transport"]
|
grpc = ["dep:bytes", "dep:ciborium", "dep:prost", "dep:prost-types", "dep:serde", "dep:tonic", "dep:tokio", "dep:tonic"]
|
||||||
# wasm service.
|
|
||||||
wasm-service = ["rpc", "dep:wasm-bindgen"]
|
|
||||||
# API-unstable public exports meant for external test/benchmarking; development only.
|
|
||||||
dev-hooks = []
|
|
||||||
# Logging of performance-related statistics; development only.
|
|
||||||
dev-logs = []
|
|
||||||
|
|
||||||
|
# DEVELOPMENT ONLY: API-unstable public exports meant for external test/benchmarking.
|
||||||
|
dev-hooks = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Mandatory dependencies.
|
# Mandatory dependencies.
|
||||||
@ -53,19 +44,14 @@ spin_sleep = "1"
|
|||||||
st3 = "0.4"
|
st3 = "0.4"
|
||||||
tai-time = "0.3"
|
tai-time = "0.3"
|
||||||
|
|
||||||
# Common RPC dependencies.
|
# gRPC service dependencies.
|
||||||
bytes = { version = "1", default-features = false, optional = true }
|
bytes = { version = "1", default-features = false, optional = true }
|
||||||
prost = { version = "0.12", optional = true }
|
prost = { version = "0.13", optional = true }
|
||||||
prost-types = { version = "0.12", optional = true }
|
prost-types = { version = "0.13", optional = true }
|
||||||
ciborium = { version = "0.2.2", optional = true }
|
ciborium = { version = "0.2.2", optional = true }
|
||||||
serde = { version = "1", optional = true }
|
serde = { version = "1", optional = true }
|
||||||
|
|
||||||
# gRPC service dependencies.
|
|
||||||
tokio = { version = "1.0", features=["net", "rt-multi-thread"], optional = true }
|
tokio = { version = "1.0", features=["net", "rt-multi-thread"], optional = true }
|
||||||
tonic = { version = "0.11", default-features = false, features=["codegen", "prost"], optional = true }
|
tonic = { version = "0.12", default-features = false, features=["codegen", "prost", "server"], optional = true }
|
||||||
|
|
||||||
# WASM service dependencies.
|
|
||||||
wasm-bindgen = { version = "0.2", optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
atomic-wait = "1.1"
|
atomic-wait = "1.1"
|
||||||
@ -77,11 +63,13 @@ mio = { version = "1.0", features = ["os-poll", "net"] }
|
|||||||
loom = "0.5"
|
loom = "0.5"
|
||||||
waker-fn = "1.1"
|
waker-fn = "1.1"
|
||||||
|
|
||||||
[build-dependencies]
|
[target.'cfg(asynchronix_grpc_codegen)'.build-dependencies]
|
||||||
tonic-build = { version = "0.11", optional = true }
|
tonic-build = { version = "0.12" }
|
||||||
|
|
||||||
[lints.rust]
|
[lints.rust]
|
||||||
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(asynchronix_loom)'] }
|
# `asynchronix_loom` flag: run loom-based tests.
|
||||||
|
# `asynchronix_grpc_codegen` flag: regenerate gRPC code from .proto definitions.
|
||||||
|
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(asynchronix_loom)', 'cfg(asynchronix_grpc_codegen)'] }
|
||||||
|
|
||||||
[[test]]
|
[[test]]
|
||||||
name = "integration"
|
name = "integration"
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
#[cfg(feature = "rpc-codegen")]
|
#[cfg(asynchronix_grpc_codegen)]
|
||||||
let builder = tonic_build::configure()
|
tonic_build::configure()
|
||||||
.build_client(false)
|
.build_client(false)
|
||||||
.out_dir("src/rpc/codegen/");
|
.out_dir("src/grpc/codegen/")
|
||||||
|
.compile(&["simulation.proto"], &["src/grpc/api/"])?;
|
||||||
#[cfg(all(feature = "rpc-codegen", not(feature = "grpc-service")))]
|
|
||||||
let builder = builder.build_server(false);
|
|
||||||
|
|
||||||
#[cfg(feature = "rpc-codegen")]
|
|
||||||
builder.compile(&["simulation.proto"], &["src/rpc/api/"])?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,6 @@ pub(super) struct PoolManager {
|
|||||||
terminate_signal: AtomicBool,
|
terminate_signal: AtomicBool,
|
||||||
/// Panic caught in a worker thread.
|
/// Panic caught in a worker thread.
|
||||||
worker_panic: Mutex<Option<Box<dyn Any + Send + 'static>>>,
|
worker_panic: Mutex<Option<Box<dyn Any + Send + 'static>>>,
|
||||||
#[cfg(feature = "dev-logs")]
|
|
||||||
/// Thread wake-up statistics.
|
|
||||||
record: Record,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PoolManager {
|
impl PoolManager {
|
||||||
@ -61,8 +58,6 @@ impl PoolManager {
|
|||||||
searching_workers: AtomicUsize::new(0),
|
searching_workers: AtomicUsize::new(0),
|
||||||
terminate_signal: AtomicBool::new(false),
|
terminate_signal: AtomicBool::new(false),
|
||||||
worker_panic: Mutex::new(None),
|
worker_panic: Mutex::new(None),
|
||||||
#[cfg(feature = "dev-logs")]
|
|
||||||
record: Record::new(pool_size),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,8 +80,6 @@ impl PoolManager {
|
|||||||
.active_workers
|
.active_workers
|
||||||
.fetch_or(1 << first_idle_worker, Ordering::Relaxed);
|
.fetch_or(1 << first_idle_worker, Ordering::Relaxed);
|
||||||
if active_workers & (1 << first_idle_worker) == 0 {
|
if active_workers & (1 << first_idle_worker) == 0 {
|
||||||
#[cfg(feature = "dev-logs")]
|
|
||||||
self.record.increment(first_idle_worker);
|
|
||||||
self.begin_worker_search();
|
self.begin_worker_search();
|
||||||
self.worker_unparkers[first_idle_worker].unpark();
|
self.worker_unparkers[first_idle_worker].unpark();
|
||||||
return;
|
return;
|
||||||
@ -117,8 +110,6 @@ impl PoolManager {
|
|||||||
.active_workers
|
.active_workers
|
||||||
.fetch_or(1 << first_idle_worker, Ordering::Relaxed);
|
.fetch_or(1 << first_idle_worker, Ordering::Relaxed);
|
||||||
if active_workers & (1 << first_idle_worker) == 0 {
|
if active_workers & (1 << first_idle_worker) == 0 {
|
||||||
#[cfg(feature = "dev-logs")]
|
|
||||||
self.record.increment(first_idle_worker);
|
|
||||||
self.begin_worker_search();
|
self.begin_worker_search();
|
||||||
self.worker_unparkers[first_idle_worker].unpark();
|
self.worker_unparkers[first_idle_worker].unpark();
|
||||||
return;
|
return;
|
||||||
@ -273,13 +264,6 @@ impl PoolManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "dev-logs")]
|
|
||||||
impl Drop for PoolManager {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
println!("Thread launch count: {:?}", self.record.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An iterator over active workers that yields their associated stealer,
|
/// An iterator over active workers that yields their associated stealer,
|
||||||
/// starting from a randomly selected active worker.
|
/// starting from a randomly selected active worker.
|
||||||
pub(super) struct ShuffledStealers<'a> {
|
pub(super) struct ShuffledStealers<'a> {
|
||||||
@ -346,27 +330,3 @@ impl<'a> Iterator for ShuffledStealers<'a> {
|
|||||||
Some(&self.stealers[current_candidate])
|
Some(&self.stealers[current_candidate])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "dev-logs")]
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct Record {
|
|
||||||
stats: Vec<AtomicUsize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "dev-logs")]
|
|
||||||
impl Record {
|
|
||||||
fn new(worker_count: usize) -> Self {
|
|
||||||
let mut stats = Vec::new();
|
|
||||||
stats.resize_with(worker_count, Default::default);
|
|
||||||
Self { stats }
|
|
||||||
}
|
|
||||||
fn increment(&self, worker_id: usize) {
|
|
||||||
self.stats[worker_id].fetch_add(1, Ordering::Relaxed);
|
|
||||||
}
|
|
||||||
fn get(&self) -> Vec<usize> {
|
|
||||||
self.stats
|
|
||||||
.iter()
|
|
||||||
.map(|s| s.load(Ordering::Relaxed))
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
8
asynchronix/src/grpc.rs
Normal file
8
asynchronix/src/grpc.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
//! Simulation management through remote procedure calls.
|
||||||
|
|
||||||
|
mod codegen;
|
||||||
|
mod key_registry;
|
||||||
|
mod run;
|
||||||
|
mod services;
|
||||||
|
|
||||||
|
pub use run::run;
|
@ -1,5 +1,4 @@
|
|||||||
// This file is @generated by prost-build.
|
// This file is @generated by prost-build.
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct Error {
|
pub struct Error {
|
||||||
#[prost(enumeration = "ErrorCode", tag = "1")]
|
#[prost(enumeration = "ErrorCode", tag = "1")]
|
||||||
@ -7,15 +6,13 @@ pub struct Error {
|
|||||||
#[prost(string, tag = "2")]
|
#[prost(string, tag = "2")]
|
||||||
pub message: ::prost::alloc::string::String,
|
pub message: ::prost::alloc::string::String,
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct EventKey {
|
pub struct EventKey {
|
||||||
#[prost(uint64, tag = "1")]
|
#[prost(uint64, tag = "1")]
|
||||||
pub subkey1: u64,
|
pub subkey1: u64,
|
||||||
#[prost(uint64, tag = "2")]
|
#[prost(uint64, tag = "2")]
|
||||||
pub subkey2: u64,
|
pub subkey2: u64,
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct InitRequest {
|
pub struct InitRequest {
|
||||||
#[prost(message, optional, tag = "1")]
|
#[prost(message, optional, tag = "1")]
|
||||||
@ -23,7 +20,6 @@ pub struct InitRequest {
|
|||||||
#[prost(bytes = "vec", tag = "2")]
|
#[prost(bytes = "vec", tag = "2")]
|
||||||
pub cfg: ::prost::alloc::vec::Vec<u8>,
|
pub cfg: ::prost::alloc::vec::Vec<u8>,
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct InitReply {
|
pub struct InitReply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
@ -33,7 +29,6 @@ pub struct InitReply {
|
|||||||
/// Nested message and enum types in `InitReply`.
|
/// Nested message and enum types in `InitReply`.
|
||||||
pub mod init_reply {
|
pub mod init_reply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
||||||
pub enum Result {
|
pub enum Result {
|
||||||
#[prost(message, tag = "1")]
|
#[prost(message, tag = "1")]
|
||||||
@ -42,10 +37,8 @@ pub mod init_reply {
|
|||||||
Error(super::Error),
|
Error(super::Error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct TimeRequest {}
|
pub struct TimeRequest {}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct TimeReply {
|
pub struct TimeReply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
@ -55,7 +48,6 @@ pub struct TimeReply {
|
|||||||
/// Nested message and enum types in `TimeReply`.
|
/// Nested message and enum types in `TimeReply`.
|
||||||
pub mod time_reply {
|
pub mod time_reply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
||||||
pub enum Result {
|
pub enum Result {
|
||||||
#[prost(message, tag = "1")]
|
#[prost(message, tag = "1")]
|
||||||
@ -64,10 +56,8 @@ pub mod time_reply {
|
|||||||
Error(super::Error),
|
Error(super::Error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct StepRequest {}
|
pub struct StepRequest {}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct StepReply {
|
pub struct StepReply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
@ -77,7 +67,6 @@ pub struct StepReply {
|
|||||||
/// Nested message and enum types in `StepReply`.
|
/// Nested message and enum types in `StepReply`.
|
||||||
pub mod step_reply {
|
pub mod step_reply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
||||||
pub enum Result {
|
pub enum Result {
|
||||||
#[prost(message, tag = "1")]
|
#[prost(message, tag = "1")]
|
||||||
@ -86,8 +75,7 @@ pub mod step_reply {
|
|||||||
Error(super::Error),
|
Error(super::Error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct StepUntilRequest {
|
pub struct StepUntilRequest {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
#[prost(oneof = "step_until_request::Deadline", tags = "1, 2")]
|
#[prost(oneof = "step_until_request::Deadline", tags = "1, 2")]
|
||||||
@ -96,8 +84,7 @@ pub struct StepUntilRequest {
|
|||||||
/// Nested message and enum types in `StepUntilRequest`.
|
/// Nested message and enum types in `StepUntilRequest`.
|
||||||
pub mod step_until_request {
|
pub mod step_until_request {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
#[derive(Clone, Copy, PartialEq, ::prost::Oneof)]
|
||||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
|
||||||
pub enum Deadline {
|
pub enum Deadline {
|
||||||
#[prost(message, tag = "1")]
|
#[prost(message, tag = "1")]
|
||||||
Time(::prost_types::Timestamp),
|
Time(::prost_types::Timestamp),
|
||||||
@ -105,7 +92,6 @@ pub mod step_until_request {
|
|||||||
Duration(::prost_types::Duration),
|
Duration(::prost_types::Duration),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct StepUntilReply {
|
pub struct StepUntilReply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
@ -115,7 +101,6 @@ pub struct StepUntilReply {
|
|||||||
/// Nested message and enum types in `StepUntilReply`.
|
/// Nested message and enum types in `StepUntilReply`.
|
||||||
pub mod step_until_reply {
|
pub mod step_until_reply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
||||||
pub enum Result {
|
pub enum Result {
|
||||||
#[prost(message, tag = "1")]
|
#[prost(message, tag = "1")]
|
||||||
@ -124,7 +109,6 @@ pub mod step_until_reply {
|
|||||||
Error(super::Error),
|
Error(super::Error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct ScheduleEventRequest {
|
pub struct ScheduleEventRequest {
|
||||||
#[prost(string, tag = "3")]
|
#[prost(string, tag = "3")]
|
||||||
@ -142,8 +126,7 @@ pub struct ScheduleEventRequest {
|
|||||||
/// Nested message and enum types in `ScheduleEventRequest`.
|
/// Nested message and enum types in `ScheduleEventRequest`.
|
||||||
pub mod schedule_event_request {
|
pub mod schedule_event_request {
|
||||||
/// Expects exactly 1 variant.
|
/// Expects exactly 1 variant.
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
#[derive(Clone, Copy, PartialEq, ::prost::Oneof)]
|
||||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
|
||||||
pub enum Deadline {
|
pub enum Deadline {
|
||||||
#[prost(message, tag = "1")]
|
#[prost(message, tag = "1")]
|
||||||
Time(::prost_types::Timestamp),
|
Time(::prost_types::Timestamp),
|
||||||
@ -151,7 +134,6 @@ pub mod schedule_event_request {
|
|||||||
Duration(::prost_types::Duration),
|
Duration(::prost_types::Duration),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct ScheduleEventReply {
|
pub struct ScheduleEventReply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
@ -161,7 +143,6 @@ pub struct ScheduleEventReply {
|
|||||||
/// Nested message and enum types in `ScheduleEventReply`.
|
/// Nested message and enum types in `ScheduleEventReply`.
|
||||||
pub mod schedule_event_reply {
|
pub mod schedule_event_reply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
||||||
pub enum Result {
|
pub enum Result {
|
||||||
#[prost(message, tag = "1")]
|
#[prost(message, tag = "1")]
|
||||||
@ -172,13 +153,11 @@ pub mod schedule_event_reply {
|
|||||||
Error(super::Error),
|
Error(super::Error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
#[derive(Clone, Copy, PartialEq, ::prost::Message)]
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
|
||||||
pub struct CancelEventRequest {
|
pub struct CancelEventRequest {
|
||||||
#[prost(message, optional, tag = "1")]
|
#[prost(message, optional, tag = "1")]
|
||||||
pub key: ::core::option::Option<EventKey>,
|
pub key: ::core::option::Option<EventKey>,
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct CancelEventReply {
|
pub struct CancelEventReply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
@ -188,7 +167,6 @@ pub struct CancelEventReply {
|
|||||||
/// Nested message and enum types in `CancelEventReply`.
|
/// Nested message and enum types in `CancelEventReply`.
|
||||||
pub mod cancel_event_reply {
|
pub mod cancel_event_reply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
||||||
pub enum Result {
|
pub enum Result {
|
||||||
#[prost(message, tag = "1")]
|
#[prost(message, tag = "1")]
|
||||||
@ -197,7 +175,6 @@ pub mod cancel_event_reply {
|
|||||||
Error(super::Error),
|
Error(super::Error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct ProcessEventRequest {
|
pub struct ProcessEventRequest {
|
||||||
#[prost(string, tag = "1")]
|
#[prost(string, tag = "1")]
|
||||||
@ -205,7 +182,6 @@ pub struct ProcessEventRequest {
|
|||||||
#[prost(bytes = "vec", tag = "2")]
|
#[prost(bytes = "vec", tag = "2")]
|
||||||
pub event: ::prost::alloc::vec::Vec<u8>,
|
pub event: ::prost::alloc::vec::Vec<u8>,
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct ProcessEventReply {
|
pub struct ProcessEventReply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
@ -215,7 +191,6 @@ pub struct ProcessEventReply {
|
|||||||
/// Nested message and enum types in `ProcessEventReply`.
|
/// Nested message and enum types in `ProcessEventReply`.
|
||||||
pub mod process_event_reply {
|
pub mod process_event_reply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
||||||
pub enum Result {
|
pub enum Result {
|
||||||
#[prost(message, tag = "1")]
|
#[prost(message, tag = "1")]
|
||||||
@ -224,7 +199,6 @@ pub mod process_event_reply {
|
|||||||
Error(super::Error),
|
Error(super::Error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct ProcessQueryRequest {
|
pub struct ProcessQueryRequest {
|
||||||
#[prost(string, tag = "1")]
|
#[prost(string, tag = "1")]
|
||||||
@ -232,7 +206,6 @@ pub struct ProcessQueryRequest {
|
|||||||
#[prost(bytes = "vec", tag = "2")]
|
#[prost(bytes = "vec", tag = "2")]
|
||||||
pub request: ::prost::alloc::vec::Vec<u8>,
|
pub request: ::prost::alloc::vec::Vec<u8>,
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct ProcessQueryReply {
|
pub struct ProcessQueryReply {
|
||||||
/// This field is hoisted because protobuf3 does not support `repeated` within
|
/// This field is hoisted because protobuf3 does not support `repeated` within
|
||||||
@ -246,7 +219,6 @@ pub struct ProcessQueryReply {
|
|||||||
/// Nested message and enum types in `ProcessQueryReply`.
|
/// Nested message and enum types in `ProcessQueryReply`.
|
||||||
pub mod process_query_reply {
|
pub mod process_query_reply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
||||||
pub enum Result {
|
pub enum Result {
|
||||||
#[prost(message, tag = "10")]
|
#[prost(message, tag = "10")]
|
||||||
@ -255,13 +227,11 @@ pub mod process_query_reply {
|
|||||||
Error(super::Error),
|
Error(super::Error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct ReadEventsRequest {
|
pub struct ReadEventsRequest {
|
||||||
#[prost(string, tag = "1")]
|
#[prost(string, tag = "1")]
|
||||||
pub sink_name: ::prost::alloc::string::String,
|
pub sink_name: ::prost::alloc::string::String,
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct ReadEventsReply {
|
pub struct ReadEventsReply {
|
||||||
/// This field is hoisted because protobuf3 does not support `repeated` within
|
/// This field is hoisted because protobuf3 does not support `repeated` within
|
||||||
@ -275,7 +245,6 @@ pub struct ReadEventsReply {
|
|||||||
/// Nested message and enum types in `ReadEventsReply`.
|
/// Nested message and enum types in `ReadEventsReply`.
|
||||||
pub mod read_events_reply {
|
pub mod read_events_reply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
||||||
pub enum Result {
|
pub enum Result {
|
||||||
#[prost(message, tag = "10")]
|
#[prost(message, tag = "10")]
|
||||||
@ -284,13 +253,11 @@ pub mod read_events_reply {
|
|||||||
Error(super::Error),
|
Error(super::Error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct OpenSinkRequest {
|
pub struct OpenSinkRequest {
|
||||||
#[prost(string, tag = "1")]
|
#[prost(string, tag = "1")]
|
||||||
pub sink_name: ::prost::alloc::string::String,
|
pub sink_name: ::prost::alloc::string::String,
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct OpenSinkReply {
|
pub struct OpenSinkReply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
@ -300,7 +267,6 @@ pub struct OpenSinkReply {
|
|||||||
/// Nested message and enum types in `OpenSinkReply`.
|
/// Nested message and enum types in `OpenSinkReply`.
|
||||||
pub mod open_sink_reply {
|
pub mod open_sink_reply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
||||||
pub enum Result {
|
pub enum Result {
|
||||||
#[prost(message, tag = "10")]
|
#[prost(message, tag = "10")]
|
||||||
@ -309,13 +275,11 @@ pub mod open_sink_reply {
|
|||||||
Error(super::Error),
|
Error(super::Error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct CloseSinkRequest {
|
pub struct CloseSinkRequest {
|
||||||
#[prost(string, tag = "1")]
|
#[prost(string, tag = "1")]
|
||||||
pub sink_name: ::prost::alloc::string::String,
|
pub sink_name: ::prost::alloc::string::String,
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct CloseSinkReply {
|
pub struct CloseSinkReply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
@ -325,7 +289,6 @@ pub struct CloseSinkReply {
|
|||||||
/// Nested message and enum types in `CloseSinkReply`.
|
/// Nested message and enum types in `CloseSinkReply`.
|
||||||
pub mod close_sink_reply {
|
pub mod close_sink_reply {
|
||||||
/// Always returns exactly 1 variant.
|
/// Always returns exactly 1 variant.
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
||||||
pub enum Result {
|
pub enum Result {
|
||||||
#[prost(message, tag = "10")]
|
#[prost(message, tag = "10")]
|
||||||
@ -335,7 +298,6 @@ pub mod close_sink_reply {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// A convenience message type for custom transport implementation.
|
/// A convenience message type for custom transport implementation.
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||||
pub struct AnyRequest {
|
pub struct AnyRequest {
|
||||||
/// Expects exactly 1 variant.
|
/// Expects exactly 1 variant.
|
||||||
@ -345,7 +307,6 @@ pub struct AnyRequest {
|
|||||||
/// Nested message and enum types in `AnyRequest`.
|
/// Nested message and enum types in `AnyRequest`.
|
||||||
pub mod any_request {
|
pub mod any_request {
|
||||||
/// Expects exactly 1 variant.
|
/// Expects exactly 1 variant.
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
|
||||||
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
#[derive(Clone, PartialEq, ::prost::Oneof)]
|
||||||
pub enum Request {
|
pub enum Request {
|
||||||
#[prost(message, tag = "1")]
|
#[prost(message, tag = "1")]
|
||||||
@ -428,7 +389,7 @@ pub mod simulation_server {
|
|||||||
use tonic::codegen::*;
|
use tonic::codegen::*;
|
||||||
/// Generated trait containing gRPC methods that should be implemented for use with SimulationServer.
|
/// Generated trait containing gRPC methods that should be implemented for use with SimulationServer.
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait Simulation: Send + Sync + 'static {
|
pub trait Simulation: std::marker::Send + std::marker::Sync + 'static {
|
||||||
async fn init(
|
async fn init(
|
||||||
&self,
|
&self,
|
||||||
request: tonic::Request<super::InitRequest>,
|
request: tonic::Request<super::InitRequest>,
|
||||||
@ -487,20 +448,18 @@ pub mod simulation_server {
|
|||||||
) -> std::result::Result<tonic::Response<super::CloseSinkReply>, tonic::Status>;
|
) -> std::result::Result<tonic::Response<super::CloseSinkReply>, tonic::Status>;
|
||||||
}
|
}
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SimulationServer<T: Simulation> {
|
pub struct SimulationServer<T> {
|
||||||
inner: _Inner<T>,
|
inner: Arc<T>,
|
||||||
accept_compression_encodings: EnabledCompressionEncodings,
|
accept_compression_encodings: EnabledCompressionEncodings,
|
||||||
send_compression_encodings: EnabledCompressionEncodings,
|
send_compression_encodings: EnabledCompressionEncodings,
|
||||||
max_decoding_message_size: Option<usize>,
|
max_decoding_message_size: Option<usize>,
|
||||||
max_encoding_message_size: Option<usize>,
|
max_encoding_message_size: Option<usize>,
|
||||||
}
|
}
|
||||||
struct _Inner<T>(Arc<T>);
|
impl<T> SimulationServer<T> {
|
||||||
impl<T: Simulation> SimulationServer<T> {
|
|
||||||
pub fn new(inner: T) -> Self {
|
pub fn new(inner: T) -> Self {
|
||||||
Self::from_arc(Arc::new(inner))
|
Self::from_arc(Arc::new(inner))
|
||||||
}
|
}
|
||||||
pub fn from_arc(inner: Arc<T>) -> Self {
|
pub fn from_arc(inner: Arc<T>) -> Self {
|
||||||
let inner = _Inner(inner);
|
|
||||||
Self {
|
Self {
|
||||||
inner,
|
inner,
|
||||||
accept_compression_encodings: Default::default(),
|
accept_compression_encodings: Default::default(),
|
||||||
@ -550,8 +509,8 @@ pub mod simulation_server {
|
|||||||
impl<T, B> tonic::codegen::Service<http::Request<B>> for SimulationServer<T>
|
impl<T, B> tonic::codegen::Service<http::Request<B>> for SimulationServer<T>
|
||||||
where
|
where
|
||||||
T: Simulation,
|
T: Simulation,
|
||||||
B: Body + Send + 'static,
|
B: Body + std::marker::Send + 'static,
|
||||||
B::Error: Into<StdError> + Send + 'static,
|
B::Error: Into<StdError> + std::marker::Send + 'static,
|
||||||
{
|
{
|
||||||
type Response = http::Response<tonic::body::BoxBody>;
|
type Response = http::Response<tonic::body::BoxBody>;
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
@ -563,7 +522,6 @@ pub mod simulation_server {
|
|||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
fn call(&mut self, req: http::Request<B>) -> Self::Future {
|
fn call(&mut self, req: http::Request<B>) -> Self::Future {
|
||||||
let inner = self.inner.clone();
|
|
||||||
match req.uri().path() {
|
match req.uri().path() {
|
||||||
"/simulation.Simulation/Init" => {
|
"/simulation.Simulation/Init" => {
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
@ -592,7 +550,6 @@ pub mod simulation_server {
|
|||||||
let max_encoding_message_size = self.max_encoding_message_size;
|
let max_encoding_message_size = self.max_encoding_message_size;
|
||||||
let inner = self.inner.clone();
|
let inner = self.inner.clone();
|
||||||
let fut = async move {
|
let fut = async move {
|
||||||
let inner = inner.0;
|
|
||||||
let method = InitSvc(inner);
|
let method = InitSvc(inner);
|
||||||
let codec = tonic::codec::ProstCodec::default();
|
let codec = tonic::codec::ProstCodec::default();
|
||||||
let mut grpc = tonic::server::Grpc::new(codec)
|
let mut grpc = tonic::server::Grpc::new(codec)
|
||||||
@ -636,7 +593,6 @@ pub mod simulation_server {
|
|||||||
let max_encoding_message_size = self.max_encoding_message_size;
|
let max_encoding_message_size = self.max_encoding_message_size;
|
||||||
let inner = self.inner.clone();
|
let inner = self.inner.clone();
|
||||||
let fut = async move {
|
let fut = async move {
|
||||||
let inner = inner.0;
|
|
||||||
let method = TimeSvc(inner);
|
let method = TimeSvc(inner);
|
||||||
let codec = tonic::codec::ProstCodec::default();
|
let codec = tonic::codec::ProstCodec::default();
|
||||||
let mut grpc = tonic::server::Grpc::new(codec)
|
let mut grpc = tonic::server::Grpc::new(codec)
|
||||||
@ -680,7 +636,6 @@ pub mod simulation_server {
|
|||||||
let max_encoding_message_size = self.max_encoding_message_size;
|
let max_encoding_message_size = self.max_encoding_message_size;
|
||||||
let inner = self.inner.clone();
|
let inner = self.inner.clone();
|
||||||
let fut = async move {
|
let fut = async move {
|
||||||
let inner = inner.0;
|
|
||||||
let method = StepSvc(inner);
|
let method = StepSvc(inner);
|
||||||
let codec = tonic::codec::ProstCodec::default();
|
let codec = tonic::codec::ProstCodec::default();
|
||||||
let mut grpc = tonic::server::Grpc::new(codec)
|
let mut grpc = tonic::server::Grpc::new(codec)
|
||||||
@ -726,7 +681,6 @@ pub mod simulation_server {
|
|||||||
let max_encoding_message_size = self.max_encoding_message_size;
|
let max_encoding_message_size = self.max_encoding_message_size;
|
||||||
let inner = self.inner.clone();
|
let inner = self.inner.clone();
|
||||||
let fut = async move {
|
let fut = async move {
|
||||||
let inner = inner.0;
|
|
||||||
let method = StepUntilSvc(inner);
|
let method = StepUntilSvc(inner);
|
||||||
let codec = tonic::codec::ProstCodec::default();
|
let codec = tonic::codec::ProstCodec::default();
|
||||||
let mut grpc = tonic::server::Grpc::new(codec)
|
let mut grpc = tonic::server::Grpc::new(codec)
|
||||||
@ -772,7 +726,6 @@ pub mod simulation_server {
|
|||||||
let max_encoding_message_size = self.max_encoding_message_size;
|
let max_encoding_message_size = self.max_encoding_message_size;
|
||||||
let inner = self.inner.clone();
|
let inner = self.inner.clone();
|
||||||
let fut = async move {
|
let fut = async move {
|
||||||
let inner = inner.0;
|
|
||||||
let method = ScheduleEventSvc(inner);
|
let method = ScheduleEventSvc(inner);
|
||||||
let codec = tonic::codec::ProstCodec::default();
|
let codec = tonic::codec::ProstCodec::default();
|
||||||
let mut grpc = tonic::server::Grpc::new(codec)
|
let mut grpc = tonic::server::Grpc::new(codec)
|
||||||
@ -818,7 +771,6 @@ pub mod simulation_server {
|
|||||||
let max_encoding_message_size = self.max_encoding_message_size;
|
let max_encoding_message_size = self.max_encoding_message_size;
|
||||||
let inner = self.inner.clone();
|
let inner = self.inner.clone();
|
||||||
let fut = async move {
|
let fut = async move {
|
||||||
let inner = inner.0;
|
|
||||||
let method = CancelEventSvc(inner);
|
let method = CancelEventSvc(inner);
|
||||||
let codec = tonic::codec::ProstCodec::default();
|
let codec = tonic::codec::ProstCodec::default();
|
||||||
let mut grpc = tonic::server::Grpc::new(codec)
|
let mut grpc = tonic::server::Grpc::new(codec)
|
||||||
@ -864,7 +816,6 @@ pub mod simulation_server {
|
|||||||
let max_encoding_message_size = self.max_encoding_message_size;
|
let max_encoding_message_size = self.max_encoding_message_size;
|
||||||
let inner = self.inner.clone();
|
let inner = self.inner.clone();
|
||||||
let fut = async move {
|
let fut = async move {
|
||||||
let inner = inner.0;
|
|
||||||
let method = ProcessEventSvc(inner);
|
let method = ProcessEventSvc(inner);
|
||||||
let codec = tonic::codec::ProstCodec::default();
|
let codec = tonic::codec::ProstCodec::default();
|
||||||
let mut grpc = tonic::server::Grpc::new(codec)
|
let mut grpc = tonic::server::Grpc::new(codec)
|
||||||
@ -910,7 +861,6 @@ pub mod simulation_server {
|
|||||||
let max_encoding_message_size = self.max_encoding_message_size;
|
let max_encoding_message_size = self.max_encoding_message_size;
|
||||||
let inner = self.inner.clone();
|
let inner = self.inner.clone();
|
||||||
let fut = async move {
|
let fut = async move {
|
||||||
let inner = inner.0;
|
|
||||||
let method = ProcessQuerySvc(inner);
|
let method = ProcessQuerySvc(inner);
|
||||||
let codec = tonic::codec::ProstCodec::default();
|
let codec = tonic::codec::ProstCodec::default();
|
||||||
let mut grpc = tonic::server::Grpc::new(codec)
|
let mut grpc = tonic::server::Grpc::new(codec)
|
||||||
@ -956,7 +906,6 @@ pub mod simulation_server {
|
|||||||
let max_encoding_message_size = self.max_encoding_message_size;
|
let max_encoding_message_size = self.max_encoding_message_size;
|
||||||
let inner = self.inner.clone();
|
let inner = self.inner.clone();
|
||||||
let fut = async move {
|
let fut = async move {
|
||||||
let inner = inner.0;
|
|
||||||
let method = ReadEventsSvc(inner);
|
let method = ReadEventsSvc(inner);
|
||||||
let codec = tonic::codec::ProstCodec::default();
|
let codec = tonic::codec::ProstCodec::default();
|
||||||
let mut grpc = tonic::server::Grpc::new(codec)
|
let mut grpc = tonic::server::Grpc::new(codec)
|
||||||
@ -1002,7 +951,6 @@ pub mod simulation_server {
|
|||||||
let max_encoding_message_size = self.max_encoding_message_size;
|
let max_encoding_message_size = self.max_encoding_message_size;
|
||||||
let inner = self.inner.clone();
|
let inner = self.inner.clone();
|
||||||
let fut = async move {
|
let fut = async move {
|
||||||
let inner = inner.0;
|
|
||||||
let method = OpenSinkSvc(inner);
|
let method = OpenSinkSvc(inner);
|
||||||
let codec = tonic::codec::ProstCodec::default();
|
let codec = tonic::codec::ProstCodec::default();
|
||||||
let mut grpc = tonic::server::Grpc::new(codec)
|
let mut grpc = tonic::server::Grpc::new(codec)
|
||||||
@ -1048,7 +996,6 @@ pub mod simulation_server {
|
|||||||
let max_encoding_message_size = self.max_encoding_message_size;
|
let max_encoding_message_size = self.max_encoding_message_size;
|
||||||
let inner = self.inner.clone();
|
let inner = self.inner.clone();
|
||||||
let fut = async move {
|
let fut = async move {
|
||||||
let inner = inner.0;
|
|
||||||
let method = CloseSinkSvc(inner);
|
let method = CloseSinkSvc(inner);
|
||||||
let codec = tonic::codec::ProstCodec::default();
|
let codec = tonic::codec::ProstCodec::default();
|
||||||
let mut grpc = tonic::server::Grpc::new(codec)
|
let mut grpc = tonic::server::Grpc::new(codec)
|
||||||
@ -1070,8 +1017,11 @@ pub mod simulation_server {
|
|||||||
Ok(
|
Ok(
|
||||||
http::Response::builder()
|
http::Response::builder()
|
||||||
.status(200)
|
.status(200)
|
||||||
.header("grpc-status", "12")
|
.header("grpc-status", tonic::Code::Unimplemented as i32)
|
||||||
.header("content-type", "application/grpc")
|
.header(
|
||||||
|
http::header::CONTENT_TYPE,
|
||||||
|
tonic::metadata::GRPC_CONTENT_TYPE,
|
||||||
|
)
|
||||||
.body(empty_body())
|
.body(empty_body())
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)
|
)
|
||||||
@ -1080,7 +1030,7 @@ pub mod simulation_server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T: Simulation> Clone for SimulationServer<T> {
|
impl<T> Clone for SimulationServer<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
let inner = self.inner.clone();
|
let inner = self.inner.clone();
|
||||||
Self {
|
Self {
|
||||||
@ -1092,17 +1042,9 @@ pub mod simulation_server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T: Simulation> Clone for _Inner<T> {
|
/// Generated gRPC service name
|
||||||
fn clone(&self) -> Self {
|
pub const SERVICE_NAME: &str = "simulation.Simulation";
|
||||||
Self(Arc::clone(&self.0))
|
impl<T> tonic::server::NamedService for SimulationServer<T> {
|
||||||
}
|
const NAME: &'static str = SERVICE_NAME;
|
||||||
}
|
|
||||||
impl<T: std::fmt::Debug> std::fmt::Debug for _Inner<T> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{:?}", self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T: Simulation> tonic::server::NamedService for SimulationServer<T> {
|
|
||||||
const NAME: &'static str = "simulation.Simulation";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,8 +2,8 @@ use std::fmt;
|
|||||||
|
|
||||||
use prost_types::Timestamp;
|
use prost_types::Timestamp;
|
||||||
|
|
||||||
|
use crate::grpc::key_registry::{KeyRegistry, KeyRegistryId};
|
||||||
use crate::registry::{EventSourceRegistry, QuerySourceRegistry};
|
use crate::registry::{EventSourceRegistry, QuerySourceRegistry};
|
||||||
use crate::rpc::key_registry::{KeyRegistry, KeyRegistryId};
|
|
||||||
use crate::simulation::Simulation;
|
use crate::simulation::Simulation;
|
||||||
|
|
||||||
use super::super::codegen::simulation::*;
|
use super::super::codegen::simulation::*;
|
||||||
@ -53,7 +53,7 @@ impl ControllerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Advances simulation time to that of the next scheduled event, processing
|
/// Advances simulation time to that of the next scheduled event, processing
|
||||||
/// that event as well as all other event scheduled for the same time.
|
/// that event as well as all other events scheduled for the same time.
|
||||||
///
|
///
|
||||||
/// Processing is gated by a (possibly blocking) call to
|
/// Processing is gated by a (possibly blocking) call to
|
||||||
/// [`Clock::synchronize()`](crate::time::Clock::synchronize) on the
|
/// [`Clock::synchronize()`](crate::time::Clock::synchronize) on the
|
@ -409,14 +409,14 @@
|
|||||||
|
|
||||||
pub(crate) mod channel;
|
pub(crate) mod channel;
|
||||||
pub(crate) mod executor;
|
pub(crate) mod executor;
|
||||||
|
#[cfg(feature = "grpc")]
|
||||||
|
pub mod grpc;
|
||||||
mod loom_exports;
|
mod loom_exports;
|
||||||
pub(crate) mod macros;
|
pub(crate) mod macros;
|
||||||
pub mod model;
|
pub mod model;
|
||||||
pub mod ports;
|
pub mod ports;
|
||||||
#[cfg(feature = "rpc")]
|
#[cfg(feature = "grpc")]
|
||||||
pub mod registry;
|
pub mod registry;
|
||||||
#[cfg(feature = "rpc")]
|
|
||||||
pub mod rpc;
|
|
||||||
pub mod simulation;
|
pub mod simulation;
|
||||||
pub mod time;
|
pub mod time;
|
||||||
pub(crate) mod util;
|
pub(crate) mod util;
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
//! Simulation management through remote procedure calls.
|
|
||||||
|
|
||||||
mod codegen;
|
|
||||||
#[cfg(feature = "grpc-service")]
|
|
||||||
pub mod grpc;
|
|
||||||
mod key_registry;
|
|
||||||
#[cfg(feature = "wasm-service")]
|
|
||||||
mod protobuf;
|
|
||||||
mod services;
|
|
||||||
#[cfg(feature = "wasm-service")]
|
|
||||||
pub mod wasm;
|
|
@ -1,146 +0,0 @@
|
|||||||
use std::error;
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
use bytes::Buf;
|
|
||||||
use prost::Message;
|
|
||||||
use serde::de::DeserializeOwned;
|
|
||||||
|
|
||||||
use crate::registry::EndpointRegistry;
|
|
||||||
use crate::rpc::key_registry::KeyRegistry;
|
|
||||||
use crate::simulation::SimInit;
|
|
||||||
|
|
||||||
use super::codegen::simulation::*;
|
|
||||||
use super::services::{ControllerService, InitService, MonitorService};
|
|
||||||
|
|
||||||
/// Protobuf-based simulation manager.
|
|
||||||
///
|
|
||||||
/// A `ProtobufService` enables the management of the lifecycle of a
|
|
||||||
/// simulation, including creating a
|
|
||||||
/// [`Simulation`](crate::simulation::Simulation), invoking its methods and
|
|
||||||
/// instantiating a new simulation.
|
|
||||||
///
|
|
||||||
/// Its methods map the various RPC service methods defined in
|
|
||||||
/// `simulation.proto`.
|
|
||||||
pub(crate) struct ProtobufService {
|
|
||||||
init_service: InitService,
|
|
||||||
controller_service: ControllerService,
|
|
||||||
monitor_service: MonitorService,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ProtobufService {
|
|
||||||
/// Creates a new `ProtobufService` without any active simulation.
|
|
||||||
///
|
|
||||||
/// The argument is a closure that takes an initialization configuration and
|
|
||||||
/// is called every time the simulation is (re)started by the remote client.
|
|
||||||
/// It must create a new `SimInit` object complemented by a registry that
|
|
||||||
/// exposes the public event and query interface.
|
|
||||||
pub(crate) fn new<F, I>(sim_gen: F) -> Self
|
|
||||||
where
|
|
||||||
F: FnMut(I) -> (SimInit, EndpointRegistry) + Send + 'static,
|
|
||||||
I: DeserializeOwned,
|
|
||||||
{
|
|
||||||
Self {
|
|
||||||
init_service: InitService::new(sim_gen),
|
|
||||||
controller_service: ControllerService::NotStarted,
|
|
||||||
monitor_service: MonitorService::NotStarted,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Processes an encoded `AnyRequest` message and returns an encoded reply.
|
|
||||||
pub(crate) fn process_request<B>(&mut self, request_buf: B) -> Result<Vec<u8>, InvalidRequest>
|
|
||||||
where
|
|
||||||
B: Buf,
|
|
||||||
{
|
|
||||||
match AnyRequest::decode(request_buf) {
|
|
||||||
Ok(AnyRequest { request: Some(req) }) => match req {
|
|
||||||
any_request::Request::InitRequest(request) => {
|
|
||||||
Ok(self.init(request).encode_to_vec())
|
|
||||||
}
|
|
||||||
any_request::Request::TimeRequest(request) => {
|
|
||||||
Ok(self.controller_service.time(request).encode_to_vec())
|
|
||||||
}
|
|
||||||
any_request::Request::StepRequest(request) => {
|
|
||||||
Ok(self.controller_service.step(request).encode_to_vec())
|
|
||||||
}
|
|
||||||
any_request::Request::StepUntilRequest(request) => {
|
|
||||||
Ok(self.controller_service.step_until(request).encode_to_vec())
|
|
||||||
}
|
|
||||||
any_request::Request::ScheduleEventRequest(request) => Ok(self
|
|
||||||
.controller_service
|
|
||||||
.schedule_event(request)
|
|
||||||
.encode_to_vec()),
|
|
||||||
any_request::Request::CancelEventRequest(request) => Ok(self
|
|
||||||
.controller_service
|
|
||||||
.cancel_event(request)
|
|
||||||
.encode_to_vec()),
|
|
||||||
any_request::Request::ProcessEventRequest(request) => Ok(self
|
|
||||||
.controller_service
|
|
||||||
.process_event(request)
|
|
||||||
.encode_to_vec()),
|
|
||||||
any_request::Request::ProcessQueryRequest(request) => Ok(self
|
|
||||||
.controller_service
|
|
||||||
.process_query(request)
|
|
||||||
.encode_to_vec()),
|
|
||||||
any_request::Request::ReadEventsRequest(request) => {
|
|
||||||
Ok(self.monitor_service.read_events(request).encode_to_vec())
|
|
||||||
}
|
|
||||||
any_request::Request::OpenSinkRequest(request) => {
|
|
||||||
Ok(self.monitor_service.open_sink(request).encode_to_vec())
|
|
||||||
}
|
|
||||||
any_request::Request::CloseSinkRequest(request) => {
|
|
||||||
Ok(self.monitor_service.close_sink(request).encode_to_vec())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Ok(AnyRequest { request: None }) => Err(InvalidRequest {
|
|
||||||
description: "the message did not contain any request".to_string(),
|
|
||||||
}),
|
|
||||||
Err(err) => Err(InvalidRequest {
|
|
||||||
description: format!("bad request: {}", err),
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initialize a simulation with the provided time.
|
|
||||||
///
|
|
||||||
/// If a simulation is already active, it is destructed and replaced with a
|
|
||||||
/// new simulation.
|
|
||||||
///
|
|
||||||
/// If the initialization time is not provided, it is initialized with the
|
|
||||||
/// epoch of `MonotonicTime` (1970-01-01 00:00:00 TAI).
|
|
||||||
fn init(&mut self, request: InitRequest) -> InitReply {
|
|
||||||
let (reply, bench) = self.init_service.init(request);
|
|
||||||
|
|
||||||
if let Some((simulation, endpoint_registry)) = bench {
|
|
||||||
self.controller_service = ControllerService::Started {
|
|
||||||
simulation,
|
|
||||||
event_source_registry: endpoint_registry.event_source_registry,
|
|
||||||
query_source_registry: endpoint_registry.query_source_registry,
|
|
||||||
key_registry: KeyRegistry::default(),
|
|
||||||
};
|
|
||||||
self.monitor_service = MonitorService::Started {
|
|
||||||
event_sink_registry: endpoint_registry.event_sink_registry,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
reply
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for ProtobufService {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
f.debug_struct("ProtobufService").finish_non_exhaustive()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub(crate) struct InvalidRequest {
|
|
||||||
description: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for InvalidRequest {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
f.write_str(&self.description)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl error::Error for InvalidRequest {}
|
|
@ -1,86 +0,0 @@
|
|||||||
//! WASM simulation service.
|
|
||||||
//!
|
|
||||||
//! This module provides [`WasmSimulationService`], a thin wrapper over a
|
|
||||||
//! [`SimulationService`] that can be use from JavaScript.
|
|
||||||
//!
|
|
||||||
//! Although it is readily possible to use a
|
|
||||||
//! [`Simulation`](crate::simulation::Simulation) object from WASM,
|
|
||||||
//! [`WasmSimulationService`] goes further by exposing the complete simulation
|
|
||||||
//! API to JavaScript through protobuf.
|
|
||||||
//!
|
|
||||||
//! Keep in mind that WASM only supports single-threaded execution and therefore
|
|
||||||
//! any simulation bench compiled to WASM should instantiate simulations with
|
|
||||||
//! either [`SimInit::new()`](crate::simulation::SimInit::new) or
|
|
||||||
//! [`SimInit::with_num_threads(1)`](crate::simulation::SimInit::with_num_threads),
|
|
||||||
//! failing which the simulation will panic upon initialization.
|
|
||||||
//!
|
|
||||||
//! [`WasmSimulationService`] is exported to the JavaScript namespace as
|
|
||||||
//! `SimulationService`, and [`WasmSimulationService::process_request`] as
|
|
||||||
//! `SimulationService.processRequest`.
|
|
||||||
|
|
||||||
use serde::de::DeserializeOwned;
|
|
||||||
use wasm_bindgen::prelude::*;
|
|
||||||
|
|
||||||
use crate::registry::EndpointRegistry;
|
|
||||||
use crate::simulation::SimInit;
|
|
||||||
|
|
||||||
use super::protobuf::ProtobufService;
|
|
||||||
|
|
||||||
/// A simulation service that can be used from JavaScript.
|
|
||||||
///
|
|
||||||
/// This would typically be used by implementing a `run` function in Rust and
|
|
||||||
/// export it to WASM:
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// #[wasm_bindgen]
|
|
||||||
/// pub fn run() -> WasmSimulationService {
|
|
||||||
/// WasmSimulationService::new(my_custom_bench_generator)
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// which can then be used on the JS side to create a `SimulationService` as a
|
|
||||||
/// JS object, e.g. with:
|
|
||||||
///
|
|
||||||
/// ```js
|
|
||||||
/// const simu = run();
|
|
||||||
///
|
|
||||||
/// // ...build a protobuf request and encode it as a `Uint8Array`...
|
|
||||||
///
|
|
||||||
/// const reply = simu.processRequest(myRequest);
|
|
||||||
///
|
|
||||||
/// // ...decode the protobuf reply...
|
|
||||||
/// ```
|
|
||||||
#[wasm_bindgen(js_name = SimulationService)]
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct WasmSimulationService(ProtobufService);
|
|
||||||
|
|
||||||
#[wasm_bindgen(js_class = SimulationService)]
|
|
||||||
impl WasmSimulationService {
|
|
||||||
/// Processes a protobuf-encoded `AnyRequest` message and returns a
|
|
||||||
/// protobuf-encoded reply.
|
|
||||||
///
|
|
||||||
/// For the Protocol Buffer definitions, see the `simulation.proto` file.
|
|
||||||
#[wasm_bindgen(js_name = processRequest)]
|
|
||||||
pub fn process_request(&mut self, request: &[u8]) -> Result<Box<[u8]>, JsError> {
|
|
||||||
self.0
|
|
||||||
.process_request(request)
|
|
||||||
.map(|reply| reply.into_boxed_slice())
|
|
||||||
.map_err(|e| JsError::new(&e.to_string()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WasmSimulationService {
|
|
||||||
/// Creates a new `SimulationService` without any active simulation.
|
|
||||||
///
|
|
||||||
/// The argument is a closure that is called every time the simulation is
|
|
||||||
/// (re)started by the remote client. It must create a new `SimInit` object
|
|
||||||
/// complemented by a registry that exposes the public event and query
|
|
||||||
/// interface.
|
|
||||||
pub fn new<F, I>(sim_gen: F) -> Self
|
|
||||||
where
|
|
||||||
F: FnMut(I) -> (SimInit, EndpointRegistry) + Send + 'static,
|
|
||||||
I: DeserializeOwned,
|
|
||||||
{
|
|
||||||
Self(ProtobufService::new(sim_gen))
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user