RustyLee: Implements initial system wake-up protocol
The Brain now broadcasts a 'Waken' command to all connected organs during its startup phase. Organs, like the Heart, transition to an 'Awake' state upon receiving this command and provide feedback. The Brain then updates its own 'LifeState' to 'Awake' once organs acknowledge the wake-up. This change establishes a fundamental handshake, ensuring that core system functions only activate once the components are initialized and responsive. It introduces the `LifeState::Awake` and `OrganCommand::Waken` states for this purpose.
This commit is contained in:
parent
a353c48d21
commit
6bf5809ed8
4 changed files with 53 additions and 17 deletions
|
|
@ -36,6 +36,8 @@ impl Brain {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_brain_loop(&mut self) {
|
fn execute_brain_loop(&mut self) {
|
||||||
|
self.broadcast_to_organs(OrganCommand::Waken);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
while let Ok(command) = self.divine_rx.try_recv() {
|
while let Ok(command) = self.divine_rx.try_recv() {
|
||||||
self.handle_divine_command(command)
|
self.handle_divine_command(command)
|
||||||
|
|
@ -50,7 +52,7 @@ impl Brain {
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Ok(message) = self.organ_rx.try_recv() {
|
while let Ok(message) = self.organ_rx.try_recv() {
|
||||||
|
self.process_organ_message(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.rest();
|
self.rest();
|
||||||
|
|
@ -133,10 +135,29 @@ impl Brain {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn broadcast_to_organs(&self, command: OrganCommand) {
|
||||||
|
for OrganSocket { tx, id } in &self.organ_sockets {
|
||||||
|
let envelope = OrganCommandEnvelope{
|
||||||
|
command: command.clone(),
|
||||||
|
issued_at: Time::time_stamp_millis(),
|
||||||
|
};
|
||||||
|
|
||||||
|
debug!("sending command to organ {:?}.", id);
|
||||||
|
_ = tx.send(envelope);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn is_ready(&self) -> bool {
|
fn is_ready(&self) -> bool {
|
||||||
self.state != LifeState::Dead &&
|
self.state != LifeState::Dead &&
|
||||||
self.state != Genisys &&
|
self.state != Genisys &&
|
||||||
self.state != Buried
|
self.state != Buried
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn process_organ_message(&mut self, message: BrainMessage) {
|
||||||
|
debug!("organ message received: {:?}", message);
|
||||||
|
if let OrganCommand::Waken = message.organ_command.command {
|
||||||
|
self.state = LifeState::Awake;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ pub enum LifeState {
|
||||||
Genisys,
|
Genisys,
|
||||||
// Sleeping,
|
// Sleeping,
|
||||||
// Wakening,
|
// Wakening,
|
||||||
// Awake,
|
Awake,
|
||||||
// DeepThought,
|
// DeepThought,
|
||||||
// ActionFocused,
|
// ActionFocused,
|
||||||
// Flight,
|
// Flight,
|
||||||
|
|
@ -23,7 +23,7 @@ impl fmt::Display for LifeState {
|
||||||
LifeState::Genisys => "In Genesis",
|
LifeState::Genisys => "In Genesis",
|
||||||
// LifeState::Sleeping => "Sleeping",
|
// LifeState::Sleeping => "Sleeping",
|
||||||
// LifeState::Wakening => "Wakening",
|
// LifeState::Wakening => "Wakening",
|
||||||
// LifeState::Awake => "Fully Awake",
|
LifeState::Awake => "Fully Awake",
|
||||||
// LifeState::DeepThought => "In Deep Thought",
|
// LifeState::DeepThought => "In Deep Thought",
|
||||||
// LifeState::ActionFocused => "Action Focused",
|
// LifeState::ActionFocused => "Action Focused",
|
||||||
// LifeState::Flight => "In Flight",
|
// LifeState::Flight => "In Flight",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::sync::mpsc::{Receiver, Sender};
|
use std::sync::mpsc::{Receiver, Sender};
|
||||||
use tracing::{debug, info, instrument};
|
use tracing::{debug, info, instrument};
|
||||||
|
use crate::lifecycle::LifeState;
|
||||||
use crate::protocols::{BrainMessage, OrganCommand, OrganCommandEnvelope, OrganResponse};
|
use crate::protocols::{BrainMessage, OrganCommand, OrganCommandEnvelope, OrganResponse};
|
||||||
use crate::system::time::Time;
|
use crate::system::time::Time;
|
||||||
|
|
||||||
|
|
@ -10,6 +11,7 @@ pub struct Heart {
|
||||||
feedback_to_brain_tx: mpsc::Sender<BrainMessage>,
|
feedback_to_brain_tx: mpsc::Sender<BrainMessage>,
|
||||||
last_beat_time: u64,
|
last_beat_time: u64,
|
||||||
timestamp: u64,
|
timestamp: u64,
|
||||||
|
life_state: LifeState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Heart {
|
impl Heart {
|
||||||
|
|
@ -20,6 +22,7 @@ impl Heart {
|
||||||
feedback_to_brain_tx: tx,
|
feedback_to_brain_tx: tx,
|
||||||
last_beat_time: 0,
|
last_beat_time: 0,
|
||||||
timestamp: 0,
|
timestamp: 0,
|
||||||
|
life_state: LifeState::Dead,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,36 +35,47 @@ impl Heart {
|
||||||
debug!("Received brain command: {:?}", envelope);
|
debug!("Received brain command: {:?}", envelope);
|
||||||
|
|
||||||
match envelope.command {
|
match envelope.command {
|
||||||
|
OrganCommand::Waken => {
|
||||||
|
self.wake_up(envelope);
|
||||||
|
}
|
||||||
|
|
||||||
OrganCommand::Beat(_) => {
|
OrganCommand::Beat(_) => {
|
||||||
if self.ready_to_beat() {
|
if self.ready_to_beat() {
|
||||||
self.beat();
|
self.beat(envelope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
self.send_response_brain(envelope, OrganResponse::Ignored)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = OrganResponse::Ok;
|
|
||||||
|
|
||||||
self.send_response_brain(envelope, response);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ready_to_beat(&self) -> bool {
|
fn ready_to_beat(&self) -> bool {
|
||||||
self.timestamp >= self.last_beat_time + 500
|
self.is_ready_state() && self.timestamp >= self.last_beat_time + 500
|
||||||
}
|
}
|
||||||
|
|
||||||
fn beat(&mut self) {
|
fn is_ready_state(&self) -> bool {
|
||||||
|
self.life_state == LifeState::Awake
|
||||||
|
}
|
||||||
|
|
||||||
|
fn beat(&mut self, command_envelope: OrganCommandEnvelope) {
|
||||||
self.last_beat_time = self.timestamp;
|
self.last_beat_time = self.timestamp;
|
||||||
info!("Beat time: {}", self.last_beat_time);
|
debug!("Beat time: {}", self.last_beat_time);
|
||||||
|
self.send_response_brain(command_envelope, OrganResponse::Ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_response_brain(&self, envelope: OrganCommandEnvelope, response: OrganResponse) {
|
fn wake_up(&mut self, command_envelope: OrganCommandEnvelope) {
|
||||||
|
self.life_state = LifeState::Awake;
|
||||||
|
debug!("Awake");
|
||||||
|
self.send_response_brain(command_envelope, OrganResponse::Ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_response_brain(&self, command_envelope: OrganCommandEnvelope, response: OrganResponse) {
|
||||||
|
|
||||||
let reply = BrainMessage {
|
let reply = BrainMessage {
|
||||||
organ_command: envelope,
|
organ_command: command_envelope,
|
||||||
responded_at: self.timestamp,
|
responded_at: Time::time_stamp_millis(),
|
||||||
response,
|
response,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::coordinates::Point3D;
|
use crate::coordinates::Point3D;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum OrganCommand {
|
pub enum OrganCommand {
|
||||||
// Sleep,
|
// Sleep,
|
||||||
// Waken,
|
Waken,
|
||||||
// Pause,
|
// Pause,
|
||||||
// Resume,
|
// Resume,
|
||||||
Beat (u32),
|
Beat (u32),
|
||||||
|
|
@ -19,6 +19,7 @@ pub enum OrganCommand {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum OrganResponse {
|
pub enum OrganResponse {
|
||||||
Ok,
|
Ok,
|
||||||
|
Ignored,
|
||||||
Rejected
|
Rejected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue