diff --git a/nexosim/src/grpc/run.rs b/nexosim/src/grpc/run.rs index 6bacfa2..d74f255 100644 --- a/nexosim/src/grpc/run.rs +++ b/nexosim/src/grpc/run.rs @@ -8,7 +8,7 @@ use serde::de::DeserializeOwned; use tonic::{transport::Server, Request, Response, Status}; use crate::registry::EndpointRegistry; -use crate::simulation::{Scheduler, Simulation, SimulationError}; +use crate::simulation::{Simulation, SimulationError}; use super::codegen::simulation::*; use super::key_registry::KeyRegistry; @@ -19,13 +19,11 @@ use super::services::{ControllerService, MonitorService}; /// /// The first 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 simulation and its scheduler, complemented by a -/// registry that exposes the public event and query interface. +/// It must create a new simulation, complemented by a registry that exposes the +/// public event and query interface. pub fn run(sim_gen: F, addr: SocketAddr) -> Result<(), Box> where - F: FnMut(I) -> Result<(Simulation, Scheduler, EndpointRegistry), SimulationError> - + Send - + 'static, + F: FnMut(I) -> Result<(Simulation, EndpointRegistry), SimulationError> + Send + 'static, I: DeserializeOwned, { run_service(GrpcSimulationService::new(sim_gen), addr) @@ -67,13 +65,11 @@ impl GrpcSimulationService { /// /// 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 simulation and its scheduler, complemented by a - /// registry that exposes the public event and query interface. + /// It must create a new simulation, complemented by a registry that exposes + /// the public event and query interface. pub(crate) fn new(sim_gen: F) -> Self where - F: FnMut(I) -> Result<(Simulation, Scheduler, EndpointRegistry), SimulationError> - + Send - + 'static, + F: FnMut(I) -> Result<(Simulation, EndpointRegistry), SimulationError> + Send + 'static, I: DeserializeOwned, { Self { diff --git a/nexosim/src/grpc/services/init_service.rs b/nexosim/src/grpc/services/init_service.rs index be5c176..9eac3f4 100644 --- a/nexosim/src/grpc/services/init_service.rs +++ b/nexosim/src/grpc/services/init_service.rs @@ -8,7 +8,7 @@ use super::{map_simulation_error, to_error}; use super::super::codegen::simulation::*; -type InitResult = Result<(Simulation, Scheduler, EndpointRegistry), SimulationError>; +type InitResult = Result<(Simulation, EndpointRegistry), SimulationError>; type DeserializationError = ciborium::de::Error; type SimGen = Box Result + Send + 'static>; @@ -27,14 +27,11 @@ impl InitService { /// /// The argument is a closure that takes a CBOR-serialized initialization /// configuration and is called every time the simulation is (re)started by - /// the remote client. It must create a new simulation and its scheduler, - /// complemented by a registry that exposes the public event and query - /// interface. + /// the remote client. It must create a new simulation complemented by a + /// registry that exposes the public event and query interface. pub(crate) fn new(mut sim_gen: F) -> Self where - F: FnMut(I) -> Result<(Simulation, Scheduler, EndpointRegistry), SimulationError> - + Send - + 'static, + F: FnMut(I) -> Result<(Simulation, EndpointRegistry), SimulationError> + Send + 'static, I: DeserializeOwned, { // Wrap `sim_gen` so it accepts a serialized init configuration. @@ -67,7 +64,13 @@ impl InitService { .and_then(|init_result| init_result.map_err(map_simulation_error)); let (reply, bench) = match reply { - Ok(bench) => (init_reply::Result::Empty(()), Some(bench)), + Ok((simulation, registry)) => { + let scheduler = simulation.scheduler(); + ( + init_reply::Result::Empty(()), + Some((simulation, scheduler, registry)), + ) + } Err(e) => (init_reply::Result::Error(e), None), }; diff --git a/nexosim/src/lib.rs b/nexosim/src/lib.rs index 9aac124..8d16d98 100644 --- a/nexosim/src/lib.rs +++ b/nexosim/src/lib.rs @@ -394,11 +394,20 @@ //! //! ```toml //! [dependencies] -//! nexosim = { version = "0.3", features = ["tracing"] } +//! nexosim = { version = "0.3.0-beta.0", features = ["tracing"] } //! ``` //! //! See the [`tracing`] module for more information. //! +//! ## gRPC server +//! +//! The `grpc` feature provides a gRPC server for remote control and monitoring, +//! e.g. from a Python client. It can be activated with: +//! +//! ```toml +//! [dependencies] +//! nexosim = { version = "0.3.0-beta.0", features = ["grpc"] } +//! ``` //! //! # Other resources //! diff --git a/nexosim/src/simulation.rs b/nexosim/src/simulation.rs index 29c6c96..67bd8ac 100644 --- a/nexosim/src/simulation.rs +++ b/nexosim/src/simulation.rs @@ -494,6 +494,12 @@ impl Simulation { } } } + + /// Returns a scheduler handle. + #[cfg(feature = "grpc")] + pub(crate) fn scheduler(&self) -> Scheduler { + Scheduler::new(self.scheduler_queue.clone(), self.time.reader()) + } } impl fmt::Debug for Simulation {