Initial network service (#2)
* initial network service * [style] unpack inbound relay
This commit is contained in:
parent
e9857d979b
commit
0fcfd92a55
|
@ -0,0 +1,5 @@
|
||||||
|
[workspace]
|
||||||
|
|
||||||
|
members = [
|
||||||
|
"nomos-services"
|
||||||
|
]
|
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "nomos-services"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
overwatch = { git = "https://github.com/logos-co/Overwatch", branch = "main" }
|
||||||
|
async-trait = "0.1"
|
||||||
|
tokio = { version = "1", features = ["sync"] }
|
||||||
|
tracing = "0.1"
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod network;
|
|
@ -0,0 +1,12 @@
|
||||||
|
use super::*;
|
||||||
|
use overwatch::services::state::ServiceState;
|
||||||
|
use tokio::sync::broadcast::Receiver;
|
||||||
|
|
||||||
|
pub trait NetworkBackend {
|
||||||
|
type Config: Clone + Send + Sync + 'static;
|
||||||
|
type State: ServiceState<Settings = Self::Config> + Clone;;
|
||||||
|
|
||||||
|
fn new(config: Self::Config) -> Self;
|
||||||
|
fn broadcast(&self, msg: NetworkData);
|
||||||
|
fn subscribe(&mut self, event: EventKind) -> Receiver<NetworkEvent>;
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
pub mod backends;
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use backends::NetworkBackend;
|
||||||
|
use overwatch::services::{
|
||||||
|
handle::ServiceStateHandle,
|
||||||
|
relay::RelayMessage,
|
||||||
|
state::{NoOperator, ServiceState},
|
||||||
|
ServiceCore, ServiceData, ServiceId,
|
||||||
|
};
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use tokio::sync::broadcast;
|
||||||
|
use tokio::sync::oneshot;
|
||||||
|
|
||||||
|
pub type NetworkData = Box<[u8]>;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum NetworkMsg {
|
||||||
|
Broadcast(NetworkData),
|
||||||
|
Subscribe {
|
||||||
|
kind: EventKind,
|
||||||
|
sender: oneshot::Sender<broadcast::Receiver<NetworkEvent>>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RelayMessage for NetworkMsg {}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum EventKind {
|
||||||
|
Message,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum NetworkEvent {
|
||||||
|
RawMessage(NetworkData),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NetworkConfig<I: NetworkBackend> {
|
||||||
|
pub backend: I::Config,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NetworkService<I: NetworkBackend + Send + 'static> {
|
||||||
|
backend: I,
|
||||||
|
service_state: ServiceStateHandle<Self>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NetworkState<I: NetworkBackend> {
|
||||||
|
_backend: I::State,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: NetworkBackend + Send + 'static> ServiceData for NetworkService<I> {
|
||||||
|
const SERVICE_ID: ServiceId = "Network";
|
||||||
|
type Settings = NetworkConfig<I>;
|
||||||
|
type State = NetworkState<I>;
|
||||||
|
type StateOperator = NoOperator<Self::State>;
|
||||||
|
type Message = NetworkMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl<I: NetworkBackend + Send + 'static> ServiceCore for NetworkService<I> {
|
||||||
|
fn init(mut service_state: ServiceStateHandle<Self>) -> Self {
|
||||||
|
Self {
|
||||||
|
backend: <I as NetworkBackend>::new(
|
||||||
|
service_state.settings_reader.get_updated_settings().backend,
|
||||||
|
),
|
||||||
|
service_state,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn run(mut self) {
|
||||||
|
let Self {
|
||||||
|
service_state: ServiceStateHandle {
|
||||||
|
mut inbound_relay, ..
|
||||||
|
},
|
||||||
|
mut backend,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
while let Some(msg) = inbound_relay.recv().await {
|
||||||
|
match msg {
|
||||||
|
NetworkMsg::Broadcast(msg) => backend.broadcast(msg),
|
||||||
|
NetworkMsg::Subscribe { kind, sender } => {
|
||||||
|
sender.send(backend.subscribe(kind)).unwrap_or_else(|_| {
|
||||||
|
tracing::warn!(
|
||||||
|
"client hung up before as subscription handle could be established"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: NetworkBackend> Clone for NetworkConfig<I> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
NetworkConfig {
|
||||||
|
backend: self.backend.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: NetworkBackend> Clone for NetworkState<I> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
NetworkState {
|
||||||
|
_backend: self._backend.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: NetworkBackend + Send + 'static> ServiceState for NetworkState<I> {
|
||||||
|
type Settings = NetworkConfig<I>;
|
||||||
|
|
||||||
|
fn from_settings(settings: &Self::Settings) -> Self {
|
||||||
|
Self {
|
||||||
|
_backend: I::State::from_settings(&settings.backend),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue