|
@@ -1,165 +0,0 @@
|
|
|
-use crate::module::{as_module_map, Module, ModuleMap};
|
|
|
-use futures_core::{ready, task::Context};
|
|
|
-use std::{cell::RefCell, fmt::Debug, future::Future, io, sync::Arc};
|
|
|
-use tokio::{
|
|
|
- macros::support::{Pin, Poll},
|
|
|
- sync::{
|
|
|
- mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
|
|
|
- oneshot,
|
|
|
- },
|
|
|
-};
|
|
|
-
|
|
|
-thread_local!(
|
|
|
- static CURRENT: RefCell<Option<Arc<FlowySystem>>> = RefCell::new(None);
|
|
|
-);
|
|
|
-
|
|
|
-#[derive(Debug)]
|
|
|
-#[allow(dead_code)]
|
|
|
-pub enum SystemCommand {
|
|
|
- Exit(i8),
|
|
|
-}
|
|
|
-
|
|
|
-pub struct FlowySystem {
|
|
|
- sys_cmd_tx: UnboundedSender<SystemCommand>,
|
|
|
-}
|
|
|
-
|
|
|
-impl FlowySystem {
|
|
|
- #[allow(dead_code)]
|
|
|
- pub fn construct<F, S>(module_factory: F, sender_factory: S) -> SystemRunner
|
|
|
- where
|
|
|
- F: FnOnce() -> Vec<Module>,
|
|
|
- S: FnOnce(ModuleMap, &Runtime),
|
|
|
- {
|
|
|
- let runtime = Arc::new(Runtime::new().unwrap());
|
|
|
- let (sys_cmd_tx, sys_cmd_rx) = unbounded_channel::<SystemCommand>();
|
|
|
- let (stop_tx, stop_rx) = oneshot::channel();
|
|
|
-
|
|
|
- runtime.spawn(SystemController {
|
|
|
- stop_tx: Some(stop_tx),
|
|
|
- sys_cmd_rx,
|
|
|
- });
|
|
|
-
|
|
|
- let module_map = as_module_map(module_factory());
|
|
|
- sender_factory(module_map, &runtime);
|
|
|
-
|
|
|
- let system = Self { sys_cmd_tx };
|
|
|
- FlowySystem::set_current(system);
|
|
|
- SystemRunner { rt: runtime, stop_rx }
|
|
|
- }
|
|
|
-
|
|
|
- #[allow(dead_code)]
|
|
|
- pub fn stop(&self) {
|
|
|
- match self.sys_cmd_tx.send(SystemCommand::Exit(0)) {
|
|
|
- Ok(_) => {}
|
|
|
- Err(e) => {
|
|
|
- log::error!("Stop system error: {}", e);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- #[allow(dead_code)]
|
|
|
- pub fn set_current(sys: FlowySystem) {
|
|
|
- CURRENT.with(|cell| {
|
|
|
- *cell.borrow_mut() = Some(Arc::new(sys));
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- #[allow(dead_code)]
|
|
|
- pub fn current() -> Arc<FlowySystem> {
|
|
|
- CURRENT.with(|cell| match *cell.borrow() {
|
|
|
- Some(ref sys) => sys.clone(),
|
|
|
- None => panic!("System is not running"),
|
|
|
- })
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-struct SystemController {
|
|
|
- stop_tx: Option<oneshot::Sender<i8>>,
|
|
|
- sys_cmd_rx: UnboundedReceiver<SystemCommand>,
|
|
|
-}
|
|
|
-
|
|
|
-impl Future for SystemController {
|
|
|
- type Output = ();
|
|
|
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
|
- loop {
|
|
|
- match ready!(Pin::new(&mut self.sys_cmd_rx).poll_recv(cx)) {
|
|
|
- None => return Poll::Ready(()),
|
|
|
- Some(cmd) => match cmd {
|
|
|
- SystemCommand::Exit(code) => {
|
|
|
- if let Some(tx) = self.stop_tx.take() {
|
|
|
- let _ = tx.send(code);
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-pub struct SystemRunner {
|
|
|
- rt: Arc<Runtime>,
|
|
|
- stop_rx: oneshot::Receiver<i8>,
|
|
|
-}
|
|
|
-
|
|
|
-impl SystemRunner {
|
|
|
- #[allow(dead_code)]
|
|
|
- pub fn run(self) -> io::Result<()> {
|
|
|
- let SystemRunner { rt, stop_rx } = self;
|
|
|
- match rt.block_on(stop_rx) {
|
|
|
- Ok(code) => {
|
|
|
- if code != 0 {
|
|
|
- Err(io::Error::new(
|
|
|
- io::ErrorKind::Other,
|
|
|
- format!("Non-zero exit code: {}", code),
|
|
|
- ))
|
|
|
- } else {
|
|
|
- Ok(())
|
|
|
- }
|
|
|
- }
|
|
|
- Err(e) => Err(io::Error::new(io::ErrorKind::Other, e)),
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- #[allow(dead_code)]
|
|
|
- pub fn spawn<F: Future<Output = ()> + 'static>(self, future: F) -> Self {
|
|
|
- self.rt.spawn(future);
|
|
|
- self
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-use crate::util::tokio_default_runtime;
|
|
|
-use tokio::{runtime, task::LocalSet};
|
|
|
-
|
|
|
-#[derive(Debug)]
|
|
|
-pub struct Runtime {
|
|
|
- local: LocalSet,
|
|
|
- rt: runtime::Runtime,
|
|
|
-}
|
|
|
-
|
|
|
-impl Runtime {
|
|
|
- #[allow(dead_code)]
|
|
|
- pub fn new() -> io::Result<Runtime> {
|
|
|
- let rt = tokio_default_runtime()?;
|
|
|
- Ok(Runtime {
|
|
|
- rt,
|
|
|
- local: LocalSet::new(),
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- #[allow(dead_code)]
|
|
|
- pub fn spawn<F>(&self, future: F) -> &Self
|
|
|
- where
|
|
|
- F: Future<Output = ()> + 'static,
|
|
|
- {
|
|
|
- self.local.spawn_local(future);
|
|
|
- self
|
|
|
- }
|
|
|
-
|
|
|
- #[allow(dead_code)]
|
|
|
- pub fn block_on<F>(&self, f: F) -> F::Output
|
|
|
- where
|
|
|
- F: Future + 'static,
|
|
|
- {
|
|
|
- self.local.block_on(&self.rt, f)
|
|
|
- }
|
|
|
-}
|