1
Fork 0

clonable scheduler (ick)

This commit is contained in:
Andy Killorin 2023-12-28 11:23:59 -06:00
parent 1d98390c8d
commit e4b7da9527
Signed by: ank
GPG key ID: B6241CA3B552BCA4
3 changed files with 28 additions and 14 deletions

View file

@ -161,7 +161,7 @@ async fn write_to_disk(state: &LiveState) -> anyhow::Result<()> {
let turtles = ron::ser::to_string_pretty(&turtles, pretty.clone())?; let turtles = ron::ser::to_string_pretty(&turtles, pretty.clone())?;
let world = bincode::serialize(&*state.world.clone().lock().await)?; let world = bincode::serialize(&*state.world.clone().lock().await)?;
let depots = ron::ser::to_string_pretty(&depots, pretty.clone())?; let depots = ron::ser::to_string_pretty(&depots, pretty.clone())?;
let tasks = ron::ser::to_string_pretty(tasks, pretty.clone())?; let tasks = ron::ser::to_string_pretty(&*tasks.lock().await, pretty.clone())?;
let path = &SAVE.get().unwrap(); let path = &SAVE.get().unwrap();
tokio::fs::write(path.join("turtles.ron"), turtles).await?; tokio::fs::write(path.join("turtles.ron"), turtles).await?;
@ -226,7 +226,8 @@ async fn read_from_disk(kill: watch::Sender<bool>) -> anyhow::Result<LiveState>
}; };
let depots = Depots::from_vec(depots); let depots = Depots::from_vec(depots);
Ok(LiveState { turtles: bound_turtles.into_iter().map(|t| Arc::new(RwLock::new(t))).collect(), tasks: scheduler, Ok(LiveState { turtles: bound_turtles.into_iter().map(|t| Arc::new(RwLock::new(t))).collect(),
tasks: Arc::new(Mutex::new(scheduler)),
world: SharedWorld::from_world(world), world: SharedWorld::from_world(world),
depots, depots,
started: Instant::now(), started: Instant::now(),
@ -244,7 +245,7 @@ struct SavedState {
struct LiveState { struct LiveState {
turtles: Vec<Arc<RwLock<turtle::Turtle>>>, turtles: Vec<Arc<RwLock<turtle::Turtle>>>,
tasks: Scheduler, tasks: Arc<Mutex<Scheduler>>,
world: blocks::SharedWorld, world: blocks::SharedWorld,
depots: Depots, depots: Depots,
started: Instant, started: Instant,
@ -260,7 +261,7 @@ impl LiveState {
}; };
let depots = Depots::from_vec(save.depots); let depots = Depots::from_vec(save.depots);
Self { turtles: turtles.into_iter().map(|t| Arc::new(RwLock::new(t))).collect(), tasks: scheduler, world: SharedWorld::from_world(save.world), Self { turtles: turtles.into_iter().map(|t| Arc::new(RwLock::new(t))).collect(), tasks: Arc::new(Mutex::new(scheduler)), world: SharedWorld::from_world(save.world),
depots, depots,
started: Instant::now(), started: Instant::now(),
kill:sender, kill:sender,

View file

@ -6,6 +6,7 @@ use crate::blocks::SharedWorld;
use crate::depot::DepotGuard; use crate::depot::DepotGuard;
use crate::depot::Depots; use crate::depot::Depots;
use crate::paths::route_facing; use crate::paths::route_facing;
use crate::tasks::Scheduler;
use anyhow::Ok; use anyhow::Ok;
@ -156,6 +157,7 @@ pub struct TurtleCommander {
max_fuel: Arc<AtomicUsize>, max_fuel: Arc<AtomicUsize>,
name: Arc<OnceCell<Name>>, name: Arc<OnceCell<Name>>,
inventory: Arc<RwLock<Option<Vec<Option<InventorySlot>>>>>, inventory: Arc<RwLock<Option<Vec<Option<InventorySlot>>>>>,
tasks: Arc<Mutex<Scheduler>>, // this feels subpar, I feel like a mpsc would do better
} }
impl fmt::Debug for TurtleCommander { impl fmt::Debug for TurtleCommander {
@ -179,6 +181,7 @@ impl TurtleCommander {
name: Arc::new(OnceCell::new_with(Some(turtle.name))), name: Arc::new(OnceCell::new_with(Some(turtle.name))),
depots: state.depots.clone(), depots: state.depots.clone(),
inventory: Default::default(), inventory: Default::default(),
tasks: state.tasks.clone(),
}) })
} }
@ -192,6 +195,7 @@ impl TurtleCommander {
name: Arc::new(OnceCell::new_with(Some(turtle.name))), name: Arc::new(OnceCell::new_with(Some(turtle.name))),
depots: state.depots.clone(), depots: state.depots.clone(),
inventory: Default::default(), inventory: Default::default(),
tasks: state.tasks.clone(),
} }
} }
@ -523,6 +527,10 @@ pub enum TurtleCommand {
Poweroff, Poweroff,
Refuel, Refuel,
CycleFront, CycleFront,
/// Name of the computer in front of the one commanded
NameFront,
/// Name of the current computer
Name,
} }
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
@ -538,6 +546,7 @@ pub(crate) enum TurtleCommandResponse {
Failure, Failure,
Item(InventorySlot), Item(InventorySlot),
Inventory(Vec<InventorySlot>), Inventory(Vec<InventorySlot>),
Name(String),
} }
impl TurtleCommand { impl TurtleCommand {

View file

@ -79,7 +79,7 @@ pub(crate) async fn register_turtle(
) -> &'static str { ) -> &'static str {
let state = &mut state.write().await; let state = &mut state.write().await;
let commander = state.get_turtle(id).await.unwrap().clone(); let commander = state.get_turtle(id).await.unwrap().clone();
state.tasks.add_turtle(&commander); state.tasks.lock().await.add_turtle(&commander);
info!("registered turtle: {id}"); info!("registered turtle: {id}");
"ACK" "ACK"
@ -94,7 +94,7 @@ pub(crate) async fn create_turtle(
let (send, receive) = mpsc::channel(1); let (send, receive) = mpsc::channel(1);
let turtle = turtle::Turtle::with_channel(id, Position::new(req.position, req.facing), req.fuel, req.fuellimit, send,receive); let turtle = turtle::Turtle::with_channel(id, Position::new(req.position, req.facing), req.fuel, req.fuellimit, send,receive);
let commander = TurtleCommander::with_turtle(&turtle, state); let commander = TurtleCommander::with_turtle(&turtle, state);
state.tasks.add_turtle(&commander); state.tasks.lock().await.add_turtle(&commander);
state.turtles.push( state.turtles.push(
Arc::new(RwLock::new( Arc::new(RwLock::new(
turtle turtle
@ -144,7 +144,8 @@ pub(crate) async fn dig(
State(state): State<SharedControl>, State(state): State<SharedControl>,
Json(req): Json<Vec3>, Json(req): Json<Vec3>,
) -> &'static str { ) -> &'static str {
let schedule = &mut state.write().await.tasks; let state = state.read().await;
let mut schedule = state.tasks.lock().await;
let size = Vec3::new(16,16,16); let size = Vec3::new(16,16,16);
schedule.add_task(Box::new(Quarry::new(req,req+size))); schedule.add_task(Box::new(Quarry::new(req,req+size)));
@ -164,7 +165,8 @@ pub(crate) async fn new_depot(
pub(crate) async fn poll( pub(crate) async fn poll(
State(state): State<SharedControl>, State(state): State<SharedControl>,
) -> &'static str { ) -> &'static str {
let schedule = &mut state.write().await.tasks; let state = state.read().await;
let mut schedule = state.tasks.lock().await;
schedule.poll().await; schedule.poll().await;
"ACK" "ACK"
@ -174,9 +176,10 @@ pub(crate) async fn shutdown(
State(state): State<SharedControl>, State(state): State<SharedControl>,
) -> &'static str { ) -> &'static str {
let signal = { let signal = {
let mut state = state.write().await; let state = state.read().await;
let signal = state.tasks.shutdown(); let scheduler = &mut state.tasks.lock().await;
state.tasks.poll().await; let signal = scheduler.shutdown();
scheduler.poll().await;
signal signal
}; };
@ -196,7 +199,7 @@ pub(crate) async fn fell(
Json(req): Json<Vec3>, Json(req): Json<Vec3>,
) -> &'static str { ) -> &'static str {
let schedule = &mut state.write().await.tasks; let schedule = &mut state.write().await.tasks;
schedule.add_task(Box::new(TreeFarm::new(req))); schedule.lock().await.add_task(Box::new(TreeFarm::new(req)));
"ACK" "ACK"
} }
@ -218,7 +221,7 @@ pub(crate) async fn cancel(
Path(id): Path<u32>, Path(id): Path<u32>,
State(state): State<SharedControl>, State(state): State<SharedControl>,
) -> &'static str { ) -> &'static str {
state.write().await.tasks.cancel(Name::from_num(id)).await; state.read().await.tasks.lock().await.cancel(Name::from_num(id)).await;
"ACK" "ACK"
} }
@ -269,7 +272,8 @@ pub(crate) async fn command(
tokio::spawn(async move { tokio::spawn(async move {
let state = &state.clone(); let state = &state.clone();
if Instant::elapsed(&state.clone().read().await.started).as_secs_f64() > STARTUP_ALLOWANCE { if Instant::elapsed(&state.clone().read().await.started).as_secs_f64() > STARTUP_ALLOWANCE {
let schedule = &mut state.write().await.tasks; let state = state.read().await;
let mut schedule = state.tasks.lock().await;
trace!("idle, polling"); trace!("idle, polling");
schedule.add_turtle(&turtle_commander.unwrap()); schedule.add_turtle(&turtle_commander.unwrap());
schedule.poll().await; schedule.poll().await;