WIP
This commit is contained in:
+95
-52
@@ -6,7 +6,12 @@ use std::{
|
||||
};
|
||||
|
||||
use hd_lib::{
|
||||
bus::{Event, EventBus, EventData}, error::HError, thread_pool::ThreadPool,
|
||||
bus::{
|
||||
Event, EventBus, EventData,
|
||||
packet::{self, Packet, PacketType},
|
||||
},
|
||||
error::HError,
|
||||
thread_pool::ThreadPool,
|
||||
};
|
||||
|
||||
use tracing::{Span, info, info_span};
|
||||
@@ -34,7 +39,7 @@ impl TcpEventBus {
|
||||
|
||||
impl TcpEventBus {
|
||||
pub fn start(&self, addr: &'static str) -> Result<(), HError> {
|
||||
let listener = TcpListener::bind(addr).map_err(HError::TcpSocketBindError)?;
|
||||
let listener = TcpListener::bind(addr)?;
|
||||
info!("Heimdall listening at {}", addr);
|
||||
for stream in listener.incoming() {
|
||||
match stream {
|
||||
@@ -50,16 +55,15 @@ impl TcpEventBus {
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
enum EventBusClientConnectionState {
|
||||
Connect,
|
||||
ReadPrelude,
|
||||
ReadCursor,
|
||||
Command,
|
||||
SendEvent,
|
||||
ReceiveAck,
|
||||
WaitEvent,
|
||||
Disconnect,
|
||||
}
|
||||
|
||||
struct EventBusClientConnection {
|
||||
stream: TcpStream,
|
||||
pub addr: String,
|
||||
stream: TcpStream,
|
||||
state: EventBusClientConnectionState,
|
||||
subscription: Option<Receiver<Arc<Event>>>,
|
||||
bus: EventBus,
|
||||
@@ -72,9 +76,7 @@ impl EventBusClientConnection {
|
||||
.map(|a| a.to_string())
|
||||
.unwrap_or("unknown".to_string());
|
||||
|
||||
stream
|
||||
.set_read_timeout(Some(Duration::from_secs(5)))
|
||||
.map_err(HError::TcpPeerError)?;
|
||||
stream.set_read_timeout(Some(Duration::from_secs(5)))?;
|
||||
|
||||
let state = EventBusClientConnectionState::Connect;
|
||||
|
||||
@@ -88,6 +90,47 @@ impl EventBusClientConnection {
|
||||
}
|
||||
}
|
||||
|
||||
fn read_ack(stream: &mut TcpStream, packet_type: PacketType) -> Result<(), HError> {
|
||||
let packet = read_packet(stream)?;
|
||||
if packet_type == packet::get_packet_type(&packet) {
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
Err(HError::ProtocolError)
|
||||
}
|
||||
|
||||
fn read_packet(stream: &mut TcpStream) -> Result<Packet, HError> {
|
||||
let mut header_buf = [0u8; 3];
|
||||
stream.read_exact(&mut header_buf)?;
|
||||
let read_state = packet::start_read_packet(&mut header_buf)?;
|
||||
|
||||
let mut buf = vec![0u8; read_state.required_buffer_size];
|
||||
stream.read_exact(&mut buf)?;
|
||||
let packet = packet::read_packet(&buf[0..], read_state)?;
|
||||
|
||||
if let Packet::Disconnect = packet {
|
||||
return Err(HError::PeerDisconnect);
|
||||
};
|
||||
|
||||
Ok(packet)
|
||||
}
|
||||
|
||||
fn write_ack(stream: &mut TcpStream, packet_type: PacketType) -> Result<(), HError> {
|
||||
let packet = Packet::create_ack_packet(packet_type);
|
||||
write_packet(stream, &packet)
|
||||
}
|
||||
|
||||
fn write_packet(stream: &mut TcpStream, packet: &Packet) -> Result<(), HError> {
|
||||
let write_state = packet::start_write_packet(packet);
|
||||
let mut buf = vec![0u8; write_state.required_buffer_size];
|
||||
packet::write_packet(&mut buf, packet, write_state)?;
|
||||
|
||||
stream.write_all(&mut buf)?;
|
||||
stream.flush()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn handle_event_bus_client(thread_pool: &ThreadPool, bus: EventBus, stream: TcpStream) -> Result<(), HError> {
|
||||
thread_pool.execute(move || {
|
||||
let mut client = EventBusClientConnection::new(bus, stream)?;
|
||||
@@ -120,11 +163,10 @@ pub fn handle_event_bus_client(thread_pool: &ThreadPool, bus: EventBus, stream:
|
||||
fn handle_event_bus_client_state(client: &mut EventBusClientConnection) -> Result<(), HError> {
|
||||
let next_state = match client.state {
|
||||
EventBusClientConnectionState::Connect => handle_state_connect(client),
|
||||
EventBusClientConnectionState::ReadPrelude => todo!(),
|
||||
EventBusClientConnectionState::ReadCursor => todo!(),
|
||||
EventBusClientConnectionState::Command => handle_state_connect(client),
|
||||
EventBusClientConnectionState::SendEvent => handle_state_send_event(client),
|
||||
EventBusClientConnectionState::ReceiveAck => todo!(),
|
||||
_ => Ok(EventBusClientConnectionState::Disconnect),
|
||||
EventBusClientConnectionState::WaitEvent => handle_state_wait_event(client),
|
||||
EventBusClientConnectionState::Disconnect => Ok(EventBusClientConnectionState::Disconnect),
|
||||
}?;
|
||||
|
||||
client.state = next_state;
|
||||
@@ -132,15 +174,34 @@ fn handle_event_bus_client_state(client: &mut EventBusClientConnection) -> Resul
|
||||
}
|
||||
|
||||
fn handle_state_connect(client: &mut EventBusClientConnection) -> Result<EventBusClientConnectionState, HError> {
|
||||
let mut buf = [0u8; 1];
|
||||
client.stream.read_exact(&mut buf).map_err(HError::TcpPeerError)?;
|
||||
if buf[0] == 1 {
|
||||
let subscription = client.bus.subscribe()?;
|
||||
client.subscription = Some(subscription);
|
||||
return Ok(EventBusClientConnectionState::SendEvent);
|
||||
}
|
||||
let Packet::Connect = read_packet(&mut client.stream)? else {
|
||||
return Ok(EventBusClientConnectionState::Disconnect);
|
||||
};
|
||||
|
||||
Ok(EventBusClientConnectionState::Disconnect)
|
||||
write_ack(&mut client.stream, PacketType::Connect)?;
|
||||
Ok(EventBusClientConnectionState::Command)
|
||||
}
|
||||
|
||||
fn handle_state_command(client: &mut EventBusClientConnection) -> Result<EventBusClientConnectionState, HError> {
|
||||
match read_packet(&mut client.stream)? {
|
||||
// TODO: Read cursor
|
||||
Packet::Subscribe(_) => {
|
||||
write_ack(&mut client.stream, PacketType::Subscribe)?;
|
||||
|
||||
let subscription = client.bus.subscribe()?;
|
||||
client.subscription = Some(subscription);
|
||||
Ok(EventBusClientConnectionState::SendEvent)
|
||||
}
|
||||
Packet::Publish(publish_packet) => {
|
||||
write_ack(&mut client.stream, PacketType::Publish)?;
|
||||
|
||||
// TODO: Possible without copying data_utf8?
|
||||
let data = String::from_utf8(publish_packet.data_utf8)?;
|
||||
client.bus.publish(EventData::new(publish_packet.event_type, &data))?;
|
||||
Ok(EventBusClientConnectionState::WaitEvent)
|
||||
}
|
||||
_ => Ok(EventBusClientConnectionState::Disconnect),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_state_send_event(client: &mut EventBusClientConnection) -> Result<EventBusClientConnectionState, HError> {
|
||||
@@ -150,56 +211,38 @@ fn handle_state_send_event(client: &mut EventBusClientConnection) -> Result<Even
|
||||
return Ok(EventBusClientConnectionState::Disconnect);
|
||||
};
|
||||
|
||||
let data_len = evt.data.data_utf8.len();
|
||||
// [ ID ] [TYPE] [ LEN ] [ DATA ]
|
||||
// 0 to 7 8 9 to 15 . . . .
|
||||
let buf_length = data_len + 17;
|
||||
let mut buf = vec![0u8; buf_length];
|
||||
write_le_bytes(evt.id, &mut buf[0..8]);
|
||||
write_le_bytes(data_len as u64, &mut buf[9..17]);
|
||||
buf[8] = evt.data.event_type;
|
||||
|
||||
for i in 17..buf_length {
|
||||
buf[i] = evt.data.data_utf8[i - 17];
|
||||
}
|
||||
|
||||
info!(
|
||||
"SEND => ID: {} TYPE: {} LEN: {} <=",
|
||||
evt.id, evt.data.event_type, data_len
|
||||
evt.id,
|
||||
evt.data.event_type,
|
||||
evt.data.data_utf8.len()
|
||||
);
|
||||
|
||||
let stream = &mut client.stream;
|
||||
stream.write(&mut buf).map_err(HError::TcpPeerError)?;
|
||||
stream.flush().map_err(HError::TcpPeerError)?;
|
||||
|
||||
let mut ack = vec![0];
|
||||
stream.read(&mut ack).map_err(HError::TcpPeerError)?;
|
||||
let packet = Packet::create_send_event_packet(evt);
|
||||
write_packet(&mut client.stream, &packet)?;
|
||||
read_ack(&mut client.stream, PacketType::SendEvent)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(EventBusClientConnectionState::Disconnect)
|
||||
}
|
||||
|
||||
fn handle_state_wait_event(client: &mut EventBusClientConnection) -> Result<EventBusClientConnectionState, HError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn write_le_bytes(v64: u64, buf: &mut [u8]) {
|
||||
let le_bytes = v64.to_le_bytes();
|
||||
buf[0] = le_bytes[0];
|
||||
buf[1] = le_bytes[1];
|
||||
buf[2] = le_bytes[2];
|
||||
buf[3] = le_bytes[3];
|
||||
buf[4] = le_bytes[4];
|
||||
buf[5] = le_bytes[5];
|
||||
buf[6] = le_bytes[6];
|
||||
buf[7] = le_bytes[7];
|
||||
buf[0..8].copy_from_slice(&le_bytes);
|
||||
}
|
||||
|
||||
impl std::fmt::Display for EventBusClientConnectionState {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let to_write = match self {
|
||||
EventBusClientConnectionState::Connect => "CONNECT",
|
||||
EventBusClientConnectionState::ReadPrelude => "READ_PRELUDE",
|
||||
EventBusClientConnectionState::ReadCursor => "READ_CURSOR",
|
||||
EventBusClientConnectionState::Command => "COMMAND",
|
||||
EventBusClientConnectionState::SendEvent => "SEND_EVENT",
|
||||
EventBusClientConnectionState::ReceiveAck => "RECEIVE_ACK",
|
||||
EventBusClientConnectionState::WaitEvent => "WAIT_EVENT",
|
||||
EventBusClientConnectionState::Disconnect => "DISCONNECT",
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user