Files @ 113e4349a706
Branch filter:

Location: CSY/reowolf/src/runtime2/communication.rs

113e4349a706 5.7 KiB application/rls-services+xml Show Annotation Show as Raw Download as Raw
Max Henger
feat: Builtin internet component
use crate::protocol::eval::*;
use super::runtime::*;
use super::component::*;

// -----------------------------------------------------------------------------
// Generic types
// -----------------------------------------------------------------------------

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct PortId(pub u32);

impl PortId {
    /// This value is not significant, it is chosen to make debugging easier: a
    /// very large port number is more likely to shine a light on bugs.
    pub fn new_invalid() -> Self {
        return Self(u32::MAX);
    }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum PortKind {
    Putter,
    Getter,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PortState {
    Open,
    BlockedDueToPeerChange,
    BlockedDueToFullBuffers,
    Closed,
}

impl PortState {
    pub fn is_blocked(&self) -> bool {
        match self {
            PortState::BlockedDueToPeerChange | PortState::BlockedDueToFullBuffers => true,
            PortState::Open | PortState::Closed => false,
        }
    }
}

pub struct Channel {
    pub putter_id: PortId,
    pub getter_id: PortId,
}

// -----------------------------------------------------------------------------
// Data messages
// -----------------------------------------------------------------------------

#[derive(Debug)]
pub struct DataMessage {
    pub data_header: MessageDataHeader,
    pub sync_header: MessageSyncHeader,
    pub content: ValueGroup,
}

#[derive(Debug)]
pub enum PortAnnotationKind {
    Getter(PortAnnotationGetter),
    Putter(PortAnnotationPutter),
}

#[derive(Debug)]
pub struct PortAnnotationGetter {
    pub self_comp_id: CompId,
    pub self_port_id: PortId,
    pub peer_comp_id: CompId,
    pub peer_port_id: PortId,
}

#[derive(Debug)]
pub struct PortAnnotationPutter {
    pub self_comp_id: CompId,
    pub self_port_id: PortId,
}

#[derive(Debug)]
pub struct MessageDataHeader {
    pub expected_mapping: Vec<(PortAnnotationKind, Option<u32>)>,
    pub new_mapping: u32,
    pub source_port: PortId,
    pub target_port: PortId,
}

// -----------------------------------------------------------------------------
// Sync messages
// -----------------------------------------------------------------------------

#[derive(Debug)]
pub struct SyncMessage {
    pub sync_header: MessageSyncHeader,
    pub content: SyncMessageContent,
}

#[derive(Debug)]
pub enum SyncLocalSolutionEntry {
    Putter(SyncSolutionPutterPort),
    Getter(SyncSolutionGetterPort),
}

pub type SyncLocalSolution = Vec<SyncLocalSolutionEntry>;

/// Getter port in a solution. Upon receiving a message it is certain about who
/// its peer is.
#[derive(Debug)]
pub struct SyncSolutionGetterPort {
    pub self_comp_id: CompId,
    pub self_port_id: PortId,
    pub peer_comp_id: CompId,
    pub peer_port_id: PortId,
    pub mapping: u32,
}

/// Putter port in a solution. A putter may not be certain about who its peer
/// component/port is.
#[derive(Debug)]
pub struct SyncSolutionPutterPort {
    pub self_comp_id: CompId,
    pub self_port_id: PortId,
    pub mapping: u32,
}

#[derive(Debug)]
pub struct SyncSolutionChannel {
    pub putter: Option<SyncSolutionPutterPort>,
    pub getter: Option<SyncSolutionGetterPort>,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum SyncRoundDecision {
    None,
    Solution,
    Failure,
}

#[derive(Debug)]
pub struct SyncPartialSolution {
    pub channel_mapping: Vec<SyncSolutionChannel>,
    pub decision: SyncRoundDecision,
}

impl Default for SyncPartialSolution {
    fn default() -> Self {
        return Self{
            channel_mapping: Vec::new(),
            decision: SyncRoundDecision::None,
        }
    }
}

#[derive(Debug)]
pub enum SyncMessageContent {
    NotificationOfLeader,
    LocalSolution(CompId, SyncLocalSolution), // local solution of the specified component
    PartialSolution(SyncPartialSolution), // partial solution of multiple components
    GlobalSolution,
    GlobalFailure,
}

// -----------------------------------------------------------------------------
// Control messages
// -----------------------------------------------------------------------------

#[derive(Debug)]
pub struct ControlMessage {
    pub(crate) id: ControlId,
    pub sender_comp_id: CompId,
    pub target_port_id: Option<PortId>,
    pub content: ControlMessageContent,
}

#[derive(Copy, Clone, Debug)]
pub enum ControlMessageContent {
    Ack,
    BlockPort(PortId),
    UnblockPort(PortId),
    ClosePort(PortId),
    PortPeerChangedBlock(PortId),
    PortPeerChangedUnblock(PortId, CompId),
}

// -----------------------------------------------------------------------------
// Messages (generic)
// -----------------------------------------------------------------------------

#[derive(Debug)]
pub struct MessageSyncHeader {
    pub sync_round: u32,
    pub sending_id: CompId,
    pub highest_id: CompId,
}

#[derive(Debug)]
pub enum Message {
    Data(DataMessage),
    Sync(SyncMessage),
    Control(ControlMessage),
    Poll,
}

impl Message {
    pub(crate) fn target_port(&self) -> Option<PortId> {
        match self {
            Message::Data(v) =>
                return Some(v.data_header.target_port),
            Message::Control(v) =>
                return v.target_port_id,
            Message::Sync(_) =>
                return None,
            Message::Poll =>
                return None,
        }
    }

    pub(crate) fn modify_target_port(&mut self, port_id: PortId) {
        match self {
            Message::Data(v) =>
                v.data_header.target_port = port_id,
            Message::Control(v) =>
                v.target_port_id = Some(port_id),
            Message::Sync(_) => unreachable!(), // should never be called for this message type
            Message::Poll => unreachable!(),
        }
    }
}