Future based scheduling

This commit is contained in:
Gregor Reitzenstein 2020-11-04 15:41:49 +01:00
parent c62c999349
commit f8160f5b16
5 changed files with 54 additions and 12 deletions

View File

@ -2,9 +2,9 @@ use std::mem;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll, Waker}; use std::task::{Context, Poll, Waker};
use std::sync::{Arc, Mutex, MutexGuard}; use std::sync::{Arc, Mutex, MutexGuard};
use std::borrow::BorrowMut;
use futures::prelude::*; use futures::prelude::*;
use futures::ready;
use futures_signals::signal::{Mutable, Signal, MutableSignalCloned, MutableLockMut}; use futures_signals::signal::{Mutable, Signal, MutableSignalCloned, MutableLockMut};
use termion::event::Key; use termion::event::Key;
@ -45,6 +45,8 @@ pub struct Sute<'a, S> {
cmds: CommandParser<'a>, cmds: CommandParser<'a>,
drain: Arc<LogDrain<'a>>, drain: Arc<LogDrain<'a>>,
future: Option<Pin<Box<dyn Future<Output=()>>>>,
} }
impl<'a, S: Unpin> Sute<'a, S> { impl<'a, S: Unpin> Sute<'a, S> {
@ -52,8 +54,9 @@ impl<'a, S: Unpin> Sute<'a, S> {
let inputs = Inputs::new(); let inputs = Inputs::new();
let state = Mutable::new(SuteState::new()); let state = Mutable::new(SuteState::new());
let cmds = CommandParser::new(); let cmds = CommandParser::new();
let future = None;
Self { state, signal, inputs, api, log, cmds, drain, } Self { state, signal, inputs, api, log, cmds, drain, future }
} }
fn run_cmd(&mut self, cmdline: String) { fn run_cmd(&mut self, cmdline: String) {
@ -62,6 +65,22 @@ impl<'a, S: Unpin> Sute<'a, S> {
Ok(matches) => { Ok(matches) => {
match matches.subcommand() { match matches.subcommand() {
Some(("quit", _)) => self.state.lock_mut().running = false, Some(("quit", _)) => self.state.lock_mut().running = false,
Some(("authenticate", m)) => {
if let Some(mut api) = self.api.clone() {
let log2 = self.log.clone();
let f = api.authentication().then(move |mut auth| {
auth.mechanisms().map(move |mechs| {
info!(log2, "Oh yeah about `authenticate` of yours:");
for mech in mechs {
info!(log2, "Mech: {}", mech);
}
})
});
self.future.replace(Box::pin(f));
} else {
error!(self.log, "No connection, can't authenticate!");
}
}
Some((s, m)) => info!(self.log, "Got Command {} with params {:?}", s, m), Some((s, m)) => info!(self.log, "Got Command {} with params {:?}", s, m),
None => error!(self.log, "No command provided."), None => error!(self.log, "No command provided."),
} }
@ -124,6 +143,11 @@ impl <'a, S: Unpin + Signal<Item=(u16,u16)>> Future for Sute<'a, S> {
return Poll::Ready(()); return Poll::Ready(());
} }
if let Some(f) = self.future.take() {
pin_mut!(f);
f.poll(cx);
}
if let Poll::Ready(Some(size)) = Pin::new(&mut self.signal).poll_change(cx) { if let Poll::Ready(Some(size)) = Pin::new(&mut self.signal).poll_change(cx) {
self.handle_resize(size); self.handle_resize(size);
} }

View File

@ -1,6 +1,7 @@
use clap::{ use clap::{
App, App,
AppSettings, AppSettings,
Arg,
ArgMatches, ArgMatches,
Error, Error,
}; };
@ -24,13 +25,17 @@ impl<'help> CommandParser<'help> {
.subcommand(App::new("quit")) .subcommand(App::new("quit"))
.subcommand(App::new("connect")) .subcommand(App::new("connect"))
.subcommand(App::new("authenticate") .subcommand(App::new("authenticate")
.arg(Arg::new("user")
.takes_value(true))
.arg(Arg::new("password")
.takes_value(true))
) )
, ,
} }
} }
pub fn parse<I: IntoIterator<Item = String>>(&mut self, iter: I) -> Result<ArgMatches, Error> { pub fn parse<I: IntoIterator<Item = String>>(&mut self, iter: I) -> Result<ArgMatches, Error> {
self.app.try_get_matches_from_mut(iter) self.app.clone().try_get_matches_from(iter)
} }
} }

View File

@ -1,6 +1,9 @@
#[macro_use] #[macro_use]
extern crate slog; extern crate slog;
#[macro_use]
extern crate futures;
use std::io; use std::io;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::thread; use std::thread;

View File

@ -1,10 +1,13 @@
use std::fmt; use std::fmt;
use std::future::Future;
use futures::FutureExt;
use slog::Logger; use slog::Logger;
use super::connection_capnp::bootstrap::Client; use super::connection_capnp::bootstrap::Client;
use super::Authentication; use super::Authentication;
#[derive(Clone)]
pub struct API { pub struct API {
inner: Client, inner: Client,
log: Logger, log: Logger,
@ -15,13 +18,15 @@ impl API {
Self { log, inner} Self { log, inner}
} }
pub async fn authentication(&mut self) -> Authentication { pub fn authentication(&mut self) -> impl Future<Output=Authentication> {
let req = self.inner.auth_request().send().promise; let req = self.inner.auth_request().send().promise;
// TODO: When's that an Err? // TODO: When's that an Err?
let res = req.await.unwrap(); req.map(|res| {
// TODO: When's that an Err? // TODO: When's that an Err?
let tmp = res.get().unwrap(); let tmp = res.unwrap();
Authentication::new(tmp.get_auth().unwrap()) let moretmp = tmp.get().unwrap();
Authentication::new(moretmp.get_auth().unwrap())
})
} }
///// Authenticate to the server. Returns true on success, false on error ///// Authenticate to the server. Returns true on success, false on error

View File

@ -1,5 +1,8 @@
use std::fmt; use std::fmt;
use std::any::Any; use std::any::Any;
use std::future::Future;
use futures::FutureExt;
use slog::Logger; use slog::Logger;
use super::auth_capnp::authentication::Client; use super::auth_capnp::authentication::Client;
@ -20,10 +23,12 @@ impl Authentication {
Self { inner } Self { inner }
} }
pub async fn mechanisms(&mut self) -> Vec<String> { pub fn mechanisms(&mut self) -> impl Future<Output=Vec<String>> {
let req = self.inner.mechanisms_request().send().promise; let req = self.inner.mechanisms_request().send().promise;
let res = req.await.unwrap(); req.map(|res| {
let tmp = res.get().unwrap(); let res = res.unwrap();
tmp.get_mechs().unwrap().iter().map(|x| x.unwrap().to_string()).collect() let tmp = res.get().unwrap();
tmp.get_mechs().unwrap().iter().map(|x| x.unwrap().to_string()).collect()
})
} }
} }