rsocket / rsocket-rust

RSocket Rust Implementation using Tokio
Apache License 2.0
199 stars 20 forks source link

Receiving error when server tries to request client. #32

Closed mahdi-shojaee closed 3 years ago

mahdi-shojaee commented 3 years ago

Thanks for this nice crate,

Sending a request to the client in the callback of the acceptor method fails.

Expected Behavior

Expected to request_response method return the response for the request.

Actual Behavior

request_response method returns error:

thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: APPLICATION_ERROR: TODO: should be error details'

Steps to Reproduce

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
    RSocketFactory::receive()
        .transport(TcpServerTransport::from("127.0.0.1:7878"))
        .acceptor(Box::new(|setup, socket| {
            println!("socket establish: setup={:?}", setup);
            tokio::spawn(async move {
                let req = Payload::builder().set_data_utf8("Hello World!").build();
                let res = socket.request_response(req).await.unwrap();
                println!("SERVER request CLIENT success: response={:?}", res);
            });
            // Return a responder.
            // You can write you own responder by implementing `RSocket` trait.
            Ok(Box::new(EchoRSocket))
        }))
        .on_start(Box::new(|| println!("echo server start success!")))
        .serve()
        .await
}

Your Environment

Darwin Mahdis-MacBook-Pro.local 17.7.0 Darwin Kernel Version 17.7.0: Thu Jun 21 22:53:14 PDT 2018; root:xnu-4570.71.2~1/RELEASE_X86_64 x86_64

Cargo.toml dependencies

[dependencies]
tokio = { version = "0.3.6", features = ["full"] }
rsocket_rust = "0.6.0"
rsocket_rust_transport_tcp = "0.6.0"

I also tried the "0.5.1" with the appropriate tokio version and also the git master branch.

Any suggestion?

jjeffcaii commented 3 years ago

Thanks for feedback! Can you show your client-side acceptor(...) code snippet? I need some information for debugging.

jjeffcaii commented 3 years ago

v0.6.0 is ok, it's the latest released version. The next version v0.7.0 will be released when tokio-v1 supported.

mahdi-shojaee commented 3 years ago

Sure:

use std::time::Duration;

use rsocket_rust::prelude::*;
use rsocket_rust::Result;
use rsocket_rust_transport_tcp::TcpClientTransport;

#[tokio::main]
async fn main() -> Result<()> {
    let client = RSocketFactory::connect()
        .transport(TcpClientTransport::from("127.0.0.1:7878"))
        .acceptor(Box::new(|| Box::new(EchoRSocket)))
        .start()
        .await
        .expect("connection failed!");

    loop {
        tokio::time::sleep(Duration::from_secs(1)).await;

        let req = Payload::builder().set_data_utf8("Mahdi").build();
        let res = client.request_response(req).await.expect("request failed!");
        println!("response: {:?}", res);    
    }
}
[dependencies]
tokio = { version = "0.3.6", features = ["full"] }
rsocket_rust = "0.6.0"
rsocket_rust_transport_tcp = "0.6.0"

I actually added the loop to ensure that client is running and can receive messages from the server while sending messages to the server.

mahdi-shojaee commented 3 years ago

Actually, the acceptor is an EchoRSocket.

jjeffcaii commented 3 years ago

It's a bug. It will be fixed soon. Thanks for reporting 👍

jjeffcaii commented 3 years ago

It will be released with v0.7.0 in the next few days. Thanks! By the way, you can use client.wait_for_close().await to block it until client disconnected from v0.7.0.

mahdi-shojaee commented 3 years ago

Ok, Thanks. My key feature for RSocket is that after the connection is established, server can also call the client. What are the main risks if I want to use it in production! (I know you mentioned do not) instead of gRPC? Also what about performance compared to gRPC (tonic)? Are you did any comparisons?

jjeffcaii commented 3 years ago

RSocket is a network protocol instead of a RPC framework. Community has a similar framework called RSocket RPC, it uses the gRPC IDL but uses RSocket as transport layer. The main risk is that it has not been fully tested and many advance features need to be implemented. I wote a simple echo benchmark, 1 KB payload by default. You can run it with just e and just b. In my MBP 2015, score is 110K QPS. To be honest, we still need to do a lot of performance tuning work.

mahdi-shojaee commented 3 years ago

Nice, Thanks for your explanations.

jjeffcaii commented 3 years ago

@mehdishojaei the v0.7.0 has been released, feel free if you have any question. Thanks! 😃

mahdi-shojaee commented 3 years ago

Well done, I will check it in the next few days. Thanks.