mirror of
https://github.com/logos-co/Overwatch.git
synced 2025-01-20 11:29:04 +00:00
Implement ping pong example.
This commit is contained in:
parent
4160cdd859
commit
79a22e9bc2
@ -3,6 +3,7 @@ resolver = "2"
|
||||
members = [
|
||||
"overwatch-rs",
|
||||
"overwatch-derive",
|
||||
"examples/ping_pong",
|
||||
]
|
||||
|
||||
[profile.release-opt]
|
||||
|
10
examples/ping_pong/Cargo.toml
Normal file
10
examples/ping_pong/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "ping_pong"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
overwatch-rs = { path = "../../overwatch-rs" }
|
||||
overwatch-derive = { path = "../../overwatch-derive" }
|
||||
async-trait = "0.1.83"
|
||||
tokio = { version = "1", features = ["macros"] }
|
17
examples/ping_pong/README.md
Normal file
17
examples/ping_pong/README.md
Normal file
@ -0,0 +1,17 @@
|
||||
# PingPong
|
||||
This example project demonstrates how to set up a basic Overwatch application in Rust.
|
||||
|
||||
### Behaviour
|
||||
This project demonstrates a simple communication pattern between two services.
|
||||
1. Every second, the `Ping` service sends a message to the `Pong` service.
|
||||
2. The `Pong` service receives the message and prints it to the console. Afterwards, it sends a message back to the `Ping` service.
|
||||
3. The `Ping` service receives the message and prints it to the console.
|
||||
|
||||
### Features
|
||||
- **Services**: Shows how to define and register services within an Overwatch application.
|
||||
- **Message Passing**: Demonstrates communication between services using the relay.
|
||||
|
||||
### About
|
||||
This project serves as a barebones template to get started with the Overwatch library.
|
||||
It provides the foundational structure for creating more complex applications.
|
||||
|
26
examples/ping_pong/src/main.rs
Normal file
26
examples/ping_pong/src/main.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// Crate
|
||||
use overwatch_derive::Services;
|
||||
use overwatch_rs::overwatch::OverwatchRunner;
|
||||
use overwatch_rs::services::handle::ServiceHandle;
|
||||
// Internal
|
||||
use crate::service_ping::PingService;
|
||||
use crate::service_pong::PongService;
|
||||
|
||||
mod service_ping;
|
||||
mod service_pong;
|
||||
mod messages;
|
||||
|
||||
#[derive(Services)]
|
||||
struct PingPong {
|
||||
ping: ServiceHandle<PingService>,
|
||||
pong: ServiceHandle<PongService>,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let ping_pong_settings = PingPongServiceSettings {
|
||||
ping: (),
|
||||
pong: (),
|
||||
};
|
||||
let ping_pong = OverwatchRunner::<PingPong>::run(ping_pong_settings, None).expect("OverwatchRunner failed");
|
||||
ping_pong.wait_finished();
|
||||
}
|
15
examples/ping_pong/src/messages.rs
Normal file
15
examples/ping_pong/src/messages.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use overwatch_rs::services::relay::RelayMessage;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PingMessage {
|
||||
Pong
|
||||
}
|
||||
|
||||
impl RelayMessage for PingMessage {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PongMessage {
|
||||
Ping
|
||||
}
|
||||
|
||||
impl RelayMessage for PongMessage {}
|
68
examples/ping_pong/src/service_ping.rs
Normal file
68
examples/ping_pong/src/service_ping.rs
Normal file
@ -0,0 +1,68 @@
|
||||
// Crates
|
||||
use std::time::Duration;
|
||||
use tokio::time::sleep;
|
||||
use overwatch_rs::DynError;
|
||||
use overwatch_rs::services::{ServiceCore, ServiceData, ServiceId};
|
||||
use overwatch_rs::services::handle::ServiceStateHandle;
|
||||
use overwatch_rs::services::state::{NoOperator, NoState};
|
||||
// Internal
|
||||
use crate::messages::{PingMessage, PongMessage};
|
||||
use crate::service_pong::PongService;
|
||||
|
||||
pub struct PingService {
|
||||
service_state_handle: ServiceStateHandle<Self>
|
||||
}
|
||||
|
||||
impl ServiceData for PingService {
|
||||
const SERVICE_ID: ServiceId = "ping";
|
||||
type Settings = ();
|
||||
type State = NoState<Self::Settings>;
|
||||
type StateOperator = NoOperator<Self::State>;
|
||||
type Message = PingMessage;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl ServiceCore for PingService {
|
||||
fn init(service_state_handle: ServiceStateHandle<Self>) -> Result<Self, DynError> {
|
||||
Ok(Self {
|
||||
service_state_handle
|
||||
})
|
||||
}
|
||||
|
||||
async fn run(self) -> Result<(), DynError> {
|
||||
let Self {
|
||||
service_state_handle
|
||||
} = self;
|
||||
|
||||
let mut inbound_relay = service_state_handle.inbound_relay;
|
||||
let pong_outbound_relay = service_state_handle.overwatch_handle.relay::<PongService>().connect().await?;
|
||||
|
||||
let mut pong_count = 0;
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
_ = sleep(Duration::from_secs(1)) => {
|
||||
println!("Sending Ping");
|
||||
pong_outbound_relay.send(PongMessage::Ping).await.unwrap();
|
||||
}
|
||||
Some(message) = inbound_relay.recv() => {
|
||||
match message {
|
||||
PingMessage::Pong => {
|
||||
println!("Received Pong");
|
||||
pong_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
true = async {
|
||||
pong_count >= 5
|
||||
} => {
|
||||
println!("Received {} Pongs. Exiting...", pong_count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
service_state_handle.overwatch_handle.shutdown().await;
|
||||
Ok(())
|
||||
}
|
||||
}
|
47
examples/ping_pong/src/service_pong.rs
Normal file
47
examples/ping_pong/src/service_pong.rs
Normal file
@ -0,0 +1,47 @@
|
||||
// Crates
|
||||
use overwatch_rs::DynError;
|
||||
use overwatch_rs::services::{ServiceCore, ServiceData, ServiceId};
|
||||
use overwatch_rs::services::handle::ServiceStateHandle;
|
||||
use overwatch_rs::services::state::{NoOperator, NoState};
|
||||
use crate::messages::{PingMessage, PongMessage};
|
||||
use crate::service_ping::PingService;
|
||||
|
||||
pub struct PongService {
|
||||
service_state_handle: ServiceStateHandle<Self>
|
||||
}
|
||||
|
||||
impl ServiceData for PongService {
|
||||
const SERVICE_ID: ServiceId = "";
|
||||
type Settings = ();
|
||||
type State = NoState<Self::Settings>;
|
||||
type StateOperator = NoOperator<Self::State>;
|
||||
type Message = PongMessage;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl ServiceCore for PongService {
|
||||
fn init(service_state_handle: ServiceStateHandle<Self>) -> Result<Self, DynError> {
|
||||
Ok(Self {
|
||||
service_state_handle
|
||||
})
|
||||
}
|
||||
|
||||
async fn run(self) -> Result<(), DynError> {
|
||||
let Self {
|
||||
service_state_handle
|
||||
} = self;
|
||||
|
||||
let mut inbound_relay = service_state_handle.inbound_relay;
|
||||
let ping_outbound_relay = service_state_handle.overwatch_handle.relay::<PingService>().connect().await?;
|
||||
|
||||
while let Some(message) = inbound_relay.recv().await {
|
||||
match message {
|
||||
PongMessage::Ping => {
|
||||
println!("Received Ping. Sending Pong.");
|
||||
ping_outbound_relay.send(PingMessage::Pong).await.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user