Skip to content

How to use GSB

Przemysław Rekucki edited this page Dec 12, 2019 · 4 revisions

Ping service example

Step 1 (Create interface definition)

Write serde serializable structure for request message.

#[derive(Serialize, Deserialize)]
struct Ping(String);

Write serde serializable structure for response message.

#[derive(Serialize, Deserialize)]
struct PingReply(String);

Write serde serializable structure for response error.

#[derive(Serialize, Deserialize)]
struct PingError(String);

Define RpcMessage trait

impl RpcMessage for Ping {
    const ID: &'static str = "ping";
    type Item = PingReply;
    type Error = PingError;
}

Service implementation

Variant 1 (std::future)

use ya_service_bus::{typed as bus, RpcMessage};

async fn server() -> Result<(), Error> {
...

   let _ = bus::bind("/local/test", |p: Ping| {
        async move {
            Ok(Pong(format!("pong {}", p.0)))
        }
   });

...

}

Variant 2 (actix)

use ya_service_bus::{actix_rpc, Handle, RpcEnvelope, RpcMessage};

#[derive(Default)]
struct PingActor(Option<Handle>);

impl Actor for PingActor {
    type Context = Context<Self>;

    fn started(&mut self, ctx: &mut Self::Context) {
        self.0 = Some(actix_rpc::bind("/local/ping", ctx.address().recipient()))
    }
}

impl Handler<RpcEnvelope<Ping>> for PingActor {
    type Result = Result<PingReply, PingError>;

    fn handle(&mut self, msg: RpcEnvelope<Ping>, _ctx: &mut Self::Context) -> Self::Result {
        Ok(PingReply(msg.into_inner().0))
    }
}

...
let addr = PingActor::default().start();
...

Calling remote method

Variant 1 (std::future)

use ya_service_bus::{typed as bus, RpcMessage};
...

let pong = bus::service("/local/test").send(Ping("ala ma kota".into()).await?;
...

Variant 2 (actix)

use ya_service_bus::actix_rpc;
...
actix_rpc::service("/local/test").send(Ping("ala ma kota".into()).and_then(|pong| { ... })
...