mirror of
https://github.com/thilo-behnke/wasm-pong.git
synced 2026-08-18 20:56:24 +00:00
118 lines
4.1 KiB
Rust
118 lines
4.1 KiB
Rust
use kafka::producer::Producer;
|
|
use crate::hash::Hasher;
|
|
use crate::kafka::{KafkaDefaultEventWriterImpl, KafkaEventReaderImpl, KafkaSessionEventReaderImpl, KafkaSessionEventWriterImpl, KafkaTopicManager};
|
|
use serde::{Serialize, Deserialize};
|
|
use serde_json::json;
|
|
use pong::event::event::{Event, EventReader, EventWriter};
|
|
|
|
pub struct SessionManager {
|
|
kafka_host: String,
|
|
sessions: Vec<Session>,
|
|
session_producer: EventWriter,
|
|
topic_manager: KafkaTopicManager
|
|
}
|
|
|
|
// TODO: On startup read the session events from kafka to restore the session id <-> hash mappings.
|
|
impl SessionManager {
|
|
pub fn new(kafka_host: &str) -> SessionManager {
|
|
SessionManager {
|
|
kafka_host: kafka_host.to_owned(),
|
|
sessions: vec![],
|
|
topic_manager: KafkaTopicManager::from("localhost:7243"),
|
|
session_producer: EventWriter::new(Box::new(KafkaDefaultEventWriterImpl::new(kafka_host)))
|
|
}
|
|
}
|
|
|
|
pub async fn create_session(&mut self) -> Result<Session, String> {
|
|
let add_partition_res = self.topic_manager.add_partition().await;
|
|
if let Err(e) = add_partition_res {
|
|
println!("Failed to create partition: {}", e);
|
|
return Err(e);
|
|
}
|
|
let session_id = add_partition_res.unwrap();
|
|
let session_hash = Hasher::hash(session_id);
|
|
let session = Session {id: session_id, hash: session_hash};
|
|
println!("Successfully created session: {:?}", session);
|
|
let json_event = serde_json::to_string(&SessionEvent::created(session.clone())).unwrap();
|
|
let session_event_write = self.session_producer.write(Event {topic: "session".to_owned(), key: None, msg: json_event});
|
|
if let Err(e) = session_event_write {
|
|
let message = format!("Failed to write session create event to kafka: {:?}", e);
|
|
println!("{}", e);
|
|
return Err(message.to_owned());
|
|
}
|
|
println!("Successfully produced session event.");
|
|
self.sessions.push(session.clone());
|
|
Ok(session)
|
|
}
|
|
|
|
pub fn get_session_reader(&self, session_id: &str) -> Result<SessionReader, String> {
|
|
let session = self.find_session(&session_id);
|
|
if let None = session {
|
|
return Err(format!("Unable to find session with hash {}", session_id))
|
|
}
|
|
let session = session.unwrap();
|
|
let event_reader = EventReader::new(Box::new(KafkaSessionEventReaderImpl::new(&self.kafka_host, &session, &["move", "status", "input"])));
|
|
Ok(SessionReader {reader: event_reader, session})
|
|
}
|
|
|
|
pub fn get_session_writer(&self, session_id: &str) -> Result<SessionWriter, String> {
|
|
let session = self.find_session(&session_id);
|
|
if let None = session {
|
|
return Err(format!("Unable to find session with hash {}", session_id))
|
|
}
|
|
let session = session.unwrap();
|
|
let event_writer = EventWriter::new(Box::new(KafkaSessionEventWriterImpl::new(&self.kafka_host)));
|
|
Ok(SessionWriter {writer: event_writer, session})
|
|
}
|
|
|
|
fn find_session(&self, session_id: &str) -> Option<Session> {
|
|
self.sessions.iter().find(|s| session_id == s.hash).map(|s| s.clone())
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Session {
|
|
pub id: u16,
|
|
pub hash: String
|
|
}
|
|
|
|
pub struct SessionWriter {
|
|
session: Session,
|
|
writer: EventWriter
|
|
}
|
|
|
|
impl SessionWriter {
|
|
pub fn write_to_session(&mut self, topic: String, msg: String) -> Result<(), String> {
|
|
let event = Event {msg, key: Some(self.session.id.to_string()), topic};
|
|
self.writer.write(event)
|
|
}
|
|
}
|
|
|
|
pub struct SessionReader {
|
|
session: Session,
|
|
reader: EventReader
|
|
}
|
|
|
|
impl SessionReader {
|
|
pub fn read_from_session(&mut self) -> Result<Vec<Event>, String> {
|
|
self.reader.read()
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize, Serialize)]
|
|
struct SessionEvent {
|
|
event_type: SessionEventType,
|
|
session: Session
|
|
}
|
|
|
|
impl SessionEvent {
|
|
pub fn created(session: Session) -> SessionEvent {
|
|
SessionEvent {event_type: SessionEventType::CREATED, session}
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize, Serialize)]
|
|
enum SessionEventType {
|
|
CREATED
|
|
}
|