use crate::{errors::EngineError, events::EventType};
use log::{debug, info, error};
use uuid::Uuid;
use zmq::Socket;
pub trait Plugin: Sync + Send {
fn start(&self, pub_socket: Socket, sub_socket: Socket) -> Result<(), EngineError>;
fn get_subscriptions(&self) -> Result<Vec<Box<dyn EventType>>, EngineError>;
fn get_id(&self) -> Uuid;
fn get_name(&self) -> String;
}
pub trait ExternalPlugin: Send + Sync {
fn start(
&self,
pub_socket: Socket,
sub_socket: Socket,
external_socket: Socket,
) -> Result<(), EngineError> {
let plugin_id = self.get_id();
debug!("{}: top of start function for external plugin", plugin_id);
loop {
debug!("{}: waiting for next message", plugin_id);
let msg = external_socket
.recv_bytes(0)
.map_err(|e| EngineError::EngineExtSocketRcvError(plugin_id, e))?;
debug!("{}: got message from external plugin", plugin_id);
if msg.is_ascii() {
let msg_str_result = std::str::from_utf8(&msg);
let msg = match msg_str_result {
Ok(m) => m,
Err(e) => {
error!("{}: Got unexpected message from plugin: could not encode to utf8; error: {} message bytes: {:?}", plugin_id, e, msg);
external_socket
.send("event-engine: bad msg", 0)
.map_err(|e| EngineError::EngineExtSocketSendError(plugin_id, e))?;
continue;
}
};
if msg == "plugin_command: quit" {
info!("{}: got quit message; exiting", plugin_id);
break;
}
if msg == "plugin_command: next_msg" {
debug!(
"{}: got next_msg command, retrieving next message",
plugin_id
);
let next_msg = sub_socket
.recv_bytes(0)
.map_err(|e| EngineError::EngineExtSubSocketRcvError(plugin_id, e))?;
debug!(
"{}: got next message, sengding over external socket",
plugin_id
);
external_socket
.send(next_msg, 0)
.map_err(|e| EngineError::EngineExtSocketSendError(plugin_id, e))?;
debug!("{}: external message sent, loop complete", plugin_id);
continue;
}
}
pub_socket
.send(msg, 0)
.map_err(|e| EngineError::EngineExtPubSocketSendError(plugin_id, e))?;
external_socket
.send("event-engine: msg published", 0)
.map_err(|e| EngineError::EngineExtSocketSendError(plugin_id, e))?;
}
Ok(())
}
fn get_tcp_port(&self) -> i32;
fn get_subscriptions(&self) -> Result<Vec<Box<dyn EventType>>, EngineError>;
fn get_id(&self) -> Uuid;
fn get_name(&self) -> String;
}