Pending a correct test of request cancellation

This commit is contained in:
2026-04-22 15:58:34 +00:00
parent 60c96964d9
commit 7f8c247d97
31 changed files with 1059 additions and 499 deletions

View File

@@ -13,7 +13,7 @@ use futures::future::LocalBoxFuture;
use futures::stream::FuturesUnordered;
use futures::{SinkExt, StreamExt, select};
use never::Never;
use orchid_base::{OrcErrv, Receipt, ReqHandle, Sym, fmt, is, log, mk_errv};
use orchid_base::{OrcErrv, Receipt, ReqHandle, Sym, fmt, is, log, mk_errv, sym};
use orchid_extension::{self as ox, AtomicFeatures as _, get_arg};
use crate::ctx::Ctx;
@@ -100,7 +100,6 @@ pub enum CmdEvent {
}
pub struct CmdRunner {
root: Root,
queue: CommandQueue,
gas: Option<u64>,
interrupted: Option<ExecCtx>,
@@ -108,7 +107,7 @@ pub struct CmdRunner {
futures: FuturesUnordered<LocalBoxFuture<'static, Option<CmdEvent>>>,
}
impl CmdRunner {
pub async fn new(root: Root, ctx: Ctx, init: impl IntoIterator<Item = Expr>) -> Self {
pub async fn new(root: &mut Root, ctx: Ctx, init: impl IntoIterator<Item = Expr>) -> Self {
let queue = CommandQueue::new(ctx.clone(), init);
let ext_builder = ox::ExtensionBuilder::new("orchid::cmd").system(CmdSystemCtor(queue.clone()));
let extension = (Extension::new(ext_inline(ext_builder, ctx.clone()).await, ctx).await)
@@ -116,16 +115,17 @@ impl CmdRunner {
let system_ctor = (extension.system_ctors().find(|ctor| ctor.decl.name == "orchid::cmd"))
.expect("Missing command system ctor");
let (cmd_root, system) = system_ctor.run(vec![]).await;
let root = root.merge(&cmd_root).await.expect("Could not merge command system into tree");
Self { futures: FuturesUnordered::new(), gas: None, root, interrupted: None, queue, system }
*root = root.merge(&cmd_root).await.expect("Could not merge command system into tree");
Self { futures: FuturesUnordered::new(), gas: None, interrupted: None, queue, system }
}
pub fn push(&self, expr: Expr) { self.queue.push(Task::RunCommand(expr)); }
#[must_use]
pub fn sys(&self) -> &System { &self.system }
#[must_use]
pub fn get_gas(&self) -> u64 { self.gas.expect("queried gas but no gas was set") }
pub fn set_gas(&mut self, gas: u64) { self.gas = Some(gas) }
pub fn disable_gas(&mut self) { self.gas = None }
pub async fn execute(&mut self) -> CmdEvent {
pub async fn execute(&mut self, root: &Root) -> CmdEvent {
let waiting_on_queue = RefCell::new(false);
let (mut spawn, mut on_spawn) = mpsc::channel::<LocalBoxFuture<Option<CmdEvent>>>(1);
let mut normalize_stream = pin!(
@@ -134,7 +134,7 @@ impl CmdRunner {
waiting_on_queue.replace(false);
let mut xctx = match self.interrupted.take() {
None => match self.queue.get_new().await {
Task::RunCommand(expr) => ExecCtx::new(self.root.clone(), expr).await,
Task::RunCommand(expr) => ExecCtx::new(root.clone(), expr).await,
Task::Sleep(until, expr) => {
let queue = self.queue.clone();
let ctx = queue.0.borrow_mut().ctx.clone();
@@ -186,7 +186,7 @@ impl CmdRunner {
let ctx = queue.0.borrow_mut().ctx.clone();
spawn
.send(Box::pin(async move {
match atom.ipc(ox::std_reqs::RunCommand).await {
match atom.ipc(ox::std_reqs::StartCommand).await {
None => Some(CmdEvent::NonCommand(val)),
Some(None) => None,
Some(Some(expr)) => {
@@ -209,8 +209,14 @@ impl CmdRunner {
loop {
let task = select!(
r_opt = self.futures.by_ref().next() => match r_opt {
Some(Some(r)) => break r,
None if *waiting_on_queue.borrow() => break CmdEvent::Settled,
Some(Some(r)) => {
eprintln!("Exiting because ");
break r
},
None if *waiting_on_queue.borrow() => {
eprintln!("Exiting because settled");
break CmdEvent::Settled
},
None | Some(None) => continue,
},
r = normalize_stream.by_ref().next() => match r {
@@ -218,7 +224,7 @@ impl CmdRunner {
Some(r) => break r,
},
task = on_spawn.by_ref().next() => match task {
None => break CmdEvent::Exit,
None => continue,
Some(r) => r,
},
);
@@ -301,14 +307,10 @@ impl ox::System for CmdSystemInst {
}),
])
}
async fn prelude(&self) -> Vec<Sym> { vec![] }
async fn prelude(&self) -> Vec<Sym> { vec![sym!("orchid")] }
fn lexers(&self) -> Vec<ox::LexerObj> { vec![] }
fn parsers(&self) -> Vec<ox::ParserObj> { vec![] }
async fn request<'a>(
&self,
_hand: Box<dyn ReqHandle<'a> + 'a>,
req: ox::ReqForSystem<Self>,
) -> Receipt<'a> {
async fn request(&self, _hand: Box<dyn ReqHandle>, req: ox::ReqForSystem<Self>) -> Receipt {
match req {}
}
}

View File

@@ -133,31 +133,31 @@ impl Extension {
}
let this = Self(weak.upgrade().unwrap());
match req {
api::ExtHostReq::Ping(ping) => handle.reply(&ping, &()).await,
api::ExtHostReq::Ping(ping) => handle.reply(&ping, ()).await,
api::ExtHostReq::IntReq(intreq) => match intreq {
api::IntReq::InternStr(s) => {
let i = is(&s.0).await;
this.0.strings.borrow_mut().insert(i.clone());
handle.reply(&s, &i.to_api()).await
handle.reply(&s, i.to_api()).await
},
api::IntReq::InternStrv(v) => {
let tokens = join_all(v.0.iter().map(|m| es(*m))).await;
this.0.strings.borrow_mut().extend(tokens.iter().cloned());
let i = iv(&tokens).await;
this.0.string_vecs.borrow_mut().insert(i.clone());
handle.reply(&v, &i.to_api()).await
handle.reply(&v, i.to_api()).await
},
api::IntReq::ExternStr(si) => {
let i = es(si.0).await;
this.0.strings.borrow_mut().insert(i.clone());
handle.reply(&si, &i.to_string()).await
handle.reply(&si, i.to_string()).await
},
api::IntReq::ExternStrv(vi) => {
let i = ev(vi.0).await;
this.0.strings.borrow_mut().extend(i.iter().cloned());
this.0.string_vecs.borrow_mut().insert(i.clone());
let markerv = i.iter().map(|t| t.to_api()).collect_vec();
handle.reply(&vi, &markerv).await
handle.reply(&vi, markerv).await
},
},
api::ExtHostReq::Fwd(ref fw @ api::Fwd { ref target, ref method, ref body }) => {
@@ -168,11 +168,11 @@ impl Extension {
.request(api::Fwded(target.clone(), *method, body.clone()))
.await
.unwrap();
handle.reply(fw, &reply).await
handle.reply(fw, reply).await
},
api::ExtHostReq::SysFwd(ref fw @ api::SysFwd(id, ref body)) => {
let sys = ctx.system_inst(id).await.unwrap();
handle.reply(fw, &sys.request(body.clone()).await).await
handle.reply(fw, sys.request(body.clone()).await).await
},
api::ExtHostReq::SubLex(sl) => {
let (rep_in, mut rep_out) = channel(0);
@@ -182,13 +182,13 @@ impl Extension {
lex_g.get(&sl.id).cloned().expect("Sublex for nonexistent lexid");
req_in.send(ReqPair(sl.clone(), rep_in)).await.unwrap();
}
handle.reply(&sl, &rep_out.next().await.unwrap()).await
handle.reply(&sl, rep_out.next().await.unwrap()).await
},
api::ExtHostReq::ExprReq(expr_req) => match expr_req {
api::ExprReq::Inspect(ins @ api::Inspect { target }) => {
let expr = ctx.exprs.get_expr(target).expect("Invalid ticket");
handle
.reply(&ins, &api::Inspected {
.reply(&ins, api::Inspected {
refcount: expr.strong_count() as u32,
location: expr.pos().to_api(),
kind: expr.to_api().await,
@@ -201,7 +201,7 @@ impl Extension {
Some(expr) => expr.print(&FmtCtxImpl::default()).await,
}
.to_api();
handle.reply(&prt, &msg).await
handle.reply(&prt, msg).await
},
api::ExprReq::Create(cre) => {
let req = Witness::of(&cre);
@@ -213,7 +213,7 @@ impl Extension {
.await;
let expr_id = expr.id();
ctx.exprs.give_expr(expr);
handle.reply(req, &expr_id).await
handle.reply(req, expr_id).await
},
},
api::ExtHostReq::LsModule(ref ls @ api::LsModule(_sys, path)) => {
@@ -246,7 +246,7 @@ impl Extension {
}
Ok(api::ModuleInfo { members })
};
handle.reply(ls, &reply).await
handle.reply(ls, reply).await
},
api::ExtHostReq::ResolveNames(ref rn) => {
let api::ResolveNames { constid, names, sys } = rn;
@@ -275,12 +275,12 @@ impl Extension {
})
.collect()
.await;
handle.reply(rn, &responses).await
handle.reply(rn, responses).await
},
api::ExtHostReq::ExtAtomPrint(ref eap @ api::ExtAtomPrint(ref atom)) => {
let atom = AtomHand::from_api(atom, Pos::None, &mut ctx.clone()).await;
let unit = atom.print(&FmtCtxImpl::default()).await;
handle.reply(eap, &unit.to_api()).await
handle.reply(eap, unit.to_api()).await
},
}
})