hey guys,
I've have a server that's running on a local socket in a cargo workspace. the client and server are using an rpc defined via tarpc, and are attempting to communicate over a unix domain socket.
this is the server code:
#[tokio::main]
async fn main() {
let socket_path=PathBuf::from("tmp/sniper.socket");
let _ = std::fs::remove_file(socket_path.clone());
let listener = UnixListener::bind(socket_path).unwrap();
let mut codec_builder=LengthDelimitedCodec::builder();
let sniper=Arc::new(Mutex::new(sniper::Sniper::new()));
tokio::spawn(async move{
loop {
let (stream,_addr)=listener.accept().await.unwrap();
let framed_stream= codec_builder.new_framed(stream);
let transport = serde_transport::new(framed_stream,Json::default());
let server=ConnectionHandler::new(sniper.clone());
let fut = server::BaseChannel::with_defaults(transport).execute(server.serve());
tokio::spawn(fut);
}
});
}
this is the client code:
#[tokio::main]
pub async fn main(){
println!("Hello from sniper client!");
// Bind a server socket
let session_id="12345";
let test_uri="test.py";
let lang="python";
let socket_path="/tmp/sniper.socket";
let mut codec_builder=LengthDelimitedCodec::builder();
let conn = UnixStream::connect(socket_path).await.unwrap();//<-23:55 where second error happens
let transport = serde_transport::new(codec_builder.new_framed(conn), Json::default());
let client=SniperServiceClient::new(Default::default(),transport).spawn();
client.add_target(tarpc::context::current(),session_id.to_string(),test_uri.to_string(),lang.to_string()).await;
let snippet=client.get_snippet(tarpc::context::current(),lang.to_string(),"if/elif/else".to_string()).await;
println!("{:?}",snippet);
}
I'm setting up the server to listen on the socket with this test script:
#get the project home
proj_home=$(git rev-parse --show-toplevel)
#build the server
(cd $proj_home/sniper && cargo build)
#build the client
(cd $proj_home/sniper-client && cargo build)
bin_path="$proj_home/target/debug"
#set up the server to activate automatically on socket connection
systemd-run --user \
--socket-property=ListenStream=/tmp/sniper.socket \
--socket-property=NoDelay=true \
$bin_path/sniper-server
however the first time I run the client(after running the test script) I get this error:
Hello from sniper client!
Err(Kind(ConnectionReset))
the second time I run the client, I get this error:
Hello from sniper client!
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 111, kind: ConnectionRefused, message: "Connection refused" }', sniper-client/src/main.rs:23:55
which is the same error I get when not using a systemd socket at all. line 23 is where the client UnixStream connects to the socket path.
I think the issue in the second case is that the socket is still there but the server is no longer running/listening. I'm not sure what the first error is about.
my understanding of systemd sockets is that they are run the associated service/command when anything connects to the associated socket, and shuts down the program when there are no more active connections, but if that was correct then there would be no difference in the first or second connection.