re-queue on startup
This commit is contained in:
parent
9b1a588aab
commit
cc29c64485
3 changed files with 34 additions and 13 deletions
|
@ -17,7 +17,7 @@ use names::Name;
|
|||
use tasks::Scheduler;
|
||||
use tokio::{sync::{
|
||||
RwLock, mpsc, OnceCell, Mutex
|
||||
}, fs};
|
||||
}, fs, time::Instant};
|
||||
use turtle::{Turtle, TurtleCommander};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use indoc::formatdoc;
|
||||
|
@ -175,6 +175,7 @@ struct LiveState {
|
|||
tasks: Scheduler,
|
||||
world: blocks::World,
|
||||
depots: Depots,
|
||||
started: Instant,
|
||||
}
|
||||
|
||||
impl LiveState {
|
||||
|
@ -197,6 +198,7 @@ impl LiveState {
|
|||
|
||||
Self { turtles: turtles.into_iter().map(|t| Arc::new(RwLock::new(t))).collect(), tasks: scheduler, world: World::from_tree(save.world),
|
||||
depots,
|
||||
started: Instant::now(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ use super::paths::route;
|
|||
/// Time (ms) to wait for a command before letting a turtle go idle
|
||||
const COMMAND_TIMEOUT: u64 = 0o372;
|
||||
/// Time (s) between turtle polls when idle
|
||||
const IDLE_TIME: u32 = 3;
|
||||
pub const IDLE_TIME: u32 = 3;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub(crate) struct Turtle {
|
||||
|
@ -314,16 +314,16 @@ pub(crate) async fn process_turtle_update(
|
|||
id: u32,
|
||||
state: &LiveState,
|
||||
update: TurtleUpdate,
|
||||
) -> anyhow::Result<TurtleCommand> {
|
||||
) -> Option<TurtleCommand> {
|
||||
let mut turtle = state
|
||||
.turtles
|
||||
.get(id as usize)
|
||||
.context("nonexisting turtle")?.write().await;
|
||||
.context("nonexisting turtle").unwrap().write().await;
|
||||
let world = &state.world;
|
||||
|
||||
if turtle.pending_update {
|
||||
turtle.pending_update = false;
|
||||
return Ok(TurtleCommand::Update);
|
||||
return Some(TurtleCommand::Update);
|
||||
}
|
||||
|
||||
if turtle.fuel > update.fuel {
|
||||
|
@ -376,12 +376,12 @@ pub(crate) async fn process_turtle_update(
|
|||
}
|
||||
turtle.queued_movement = cmd.unit(turtle.position.dir);
|
||||
info!("{}: {cmd:?}", turtle.name.to_str());
|
||||
return Ok(cmd);
|
||||
return Some(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
trace!("{} idle, connected", turtle.name.to_str());
|
||||
Ok(TurtleCommand::Wait(IDLE_TIME))
|
||||
None
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use log::trace;
|
||||
use tokio;
|
||||
use blocks::Vec3;
|
||||
use tokio::time::Instant;
|
||||
use crate::fell::TreeFarm;
|
||||
use crate::mine::Mine;
|
||||
use crate::turtle::IDLE_TIME;
|
||||
use crate::turtle::TurtleCommandResponse;
|
||||
use crate::turtle::TurtleCommander;
|
||||
use crate::turtle::TurtleInfo;
|
||||
|
@ -29,6 +31,10 @@ use indoc::formatdoc;
|
|||
use crate::PORT;
|
||||
use tokio::fs;
|
||||
|
||||
/// Time (s) after boot to start allocating turtles to tasks
|
||||
/// too short of a time could make fast-booting turtles do far away tasks over closer ones
|
||||
const STARTUP_ALLOWANCE: f64 = 4.0;
|
||||
|
||||
pub fn turtle_api() -> Router<SharedControl> {
|
||||
Router::new()
|
||||
.route("/new", post(create_turtle))
|
||||
|
@ -193,16 +199,29 @@ pub(crate) async fn command(
|
|||
Json(req): Json<turtle::TurtleUpdate>,
|
||||
) -> Json<turtle::TurtleCommand> {
|
||||
trace!("reply from turtle {id}: {req:?}");
|
||||
let mut state = &mut state.read().await;
|
||||
let state_guard = state.clone().read_owned().await;
|
||||
|
||||
if id as usize > state.turtles.len() {
|
||||
if id as usize > state_guard.turtles.len() {
|
||||
return Json(turtle::TurtleCommand::Update);
|
||||
}
|
||||
|
||||
Json(
|
||||
turtle::process_turtle_update(id, &mut state, req).await
|
||||
.unwrap_or(turtle::TurtleCommand::Update)
|
||||
)
|
||||
let command = turtle::process_turtle_update(id, &state_guard, req).await;
|
||||
|
||||
let command = match command {
|
||||
Some(command) => command,
|
||||
None => {
|
||||
tokio::spawn(async move {
|
||||
let state = &state.clone();
|
||||
if Instant::elapsed(&state.clone().read().await.started).as_secs_f64() > STARTUP_ALLOWANCE {
|
||||
let schedule = &mut state.write().await.tasks;
|
||||
schedule.poll().await;
|
||||
}
|
||||
});
|
||||
turtle::TurtleCommand::Wait(IDLE_TIME)
|
||||
},
|
||||
};
|
||||
|
||||
Json(command)
|
||||
}
|
||||
|
||||
pub(crate) async fn client() -> String {
|
||||
|
|
Loading…
Reference in a new issue