karyon_jsonrpc/server/
quic.rs1use std::sync::Arc;
5
6use log::{debug, error};
7
8use karyon_core::async_util::{select, Either, TaskResult};
9
10use karyon_net::{
11 framed,
12 quic::{QuicConn, QuicIncoming},
13 FramedConn, StreamMux,
14};
15
16use crate::{
17 codec::JsonCodec,
18 error::Result,
19 message,
20 server::{
21 channel::Channel,
22 dispatch::{sanity_check, Handler, NewRequest, SanityCheckResult},
23 Server, CHANNEL_SUBSCRIPTION_BUFFER_SIZE,
24 },
25};
26
27impl Server {
28 pub(super) fn handle_quic_incoming(self: &Arc<Self>, incoming: QuicIncoming) {
30 let peer = incoming.peer_endpoint();
31 let server = self.clone();
32 self.task_group.spawn(async move {
33 match incoming.handshake().await {
35 Ok(quic_conn) => server.handle_quic_conn(quic_conn),
36 Err(err) => debug!("QUIC handshake with {peer} failed: {err}"),
37 }
38 });
39 }
40
41 fn handle_quic_conn(self: &Arc<Self>, quic_conn: QuicConn) {
44 let peer = quic_conn.peer_endpoint().ok();
45 debug!("Handle QUIC connection {peer:?}");
46
47 self.task_group.spawn_then(
48 quic_accept_streams_task(self.clone(), Arc::new(quic_conn)),
49 move |result: TaskResult<Result<()>>| async move {
50 if let TaskResult::Completed(Err(err)) = result {
51 debug!("QUIC conn {peer:?} dropped: {err}");
52 } else {
53 debug!("QUIC conn {peer:?} dropped");
54 }
55 },
56 );
57 }
58}
59
60async fn quic_accept_streams_task(server: Arc<Server>, quic_conn: Arc<QuicConn>) -> Result<()> {
61 let codec = JsonCodec::default();
62 loop {
63 let stream = quic_conn.accept_stream().await?;
64 let conn = framed(stream, codec.clone());
65 server
66 .task_group
67 .spawn(quic_handle_stream_task(server.clone(), conn));
68 }
69}
70
71async fn quic_handle_stream_task(server: Arc<Server>, conn: FramedConn<JsonCodec>) -> Result<()> {
72 if let Err(err) = handle_quic_stream(server, conn).await {
73 error!("Handle QUIC stream: {err}");
74 }
75 Ok(())
76}
77
78async fn handle_quic_stream(server: Arc<Server>, mut conn: FramedConn<JsonCodec>) -> Result<()> {
81 let msg = conn.recv_msg().await?;
82
83 let req = match sanity_check(msg) {
84 SanityCheckResult::NewReq(req) => req,
85 SanityCheckResult::ErrRes(res) => {
86 conn.send_msg(serde_json::json!(res)).await?;
87 return Ok(());
88 }
89 };
90
91 let is_pubsub = matches!(
95 server.resolve_handler(&req.srvc_name, &req.method_name, true),
96 Handler::Pubsub(_)
97 );
98
99 if is_pubsub {
100 return handle_quic_subscription(server, conn, req).await;
101 }
102
103 let msg = serde_json::to_value(&req.msg).expect("serializable request");
104 let response = server.handle_request(None, msg).await;
105 debug!("--> {response}");
106 conn.send_msg(serde_json::json!(response)).await?;
107 Ok(())
108}
109
110async fn handle_quic_subscription(
113 server: Arc<Server>,
114 conn: FramedConn<JsonCodec>,
115 req: NewRequest,
116) -> Result<()> {
117 let (ch_tx, ch_rx) = async_channel::bounded(CHANNEL_SUBSCRIPTION_BUFFER_SIZE);
118 let channel = Channel::new(ch_tx);
119
120 let method = match server.resolve_handler(&req.srvc_name, &req.method_name, true) {
121 Handler::Pubsub(m) => m,
122 _ => unreachable!("pubsub method presence checked by caller"),
123 };
124
125 let params = req.msg.params.unwrap_or(serde_json::json!(()));
126 let result = method(channel.clone(), req.msg.method, params).await;
127
128 let response = match result {
129 Ok(res) => message::Response {
130 result: Some(res),
131 id: Some(req.msg.id),
132 ..Default::default()
133 },
134 Err(err) => {
135 let mut conn = conn;
136 let response = err.to_response(Some(req.msg.id), None);
137 conn.send_msg(serde_json::json!(response)).await?;
138 return Ok(());
139 }
140 };
141
142 debug!("--> {response}");
143
144 let (mut reader, mut writer) = conn.split();
145 writer.send_msg(serde_json::json!(response)).await?;
146
147 let notification_encoder = server.config.notification_encoder;
148
149 loop {
150 match select(ch_rx.recv(), reader.recv_msg()).await {
151 Either::Left(nt) => {
152 let nt = nt?;
153 let notification = notification_encoder(nt);
154 debug!("--> {notification}");
155 writer.send_msg(serde_json::json!(notification)).await?;
156 }
157 Either::Right(msg) => match msg {
158 Ok(msg) => {
159 let response = server.handle_request(Some(channel.clone()), msg).await;
160 debug!("--> {response}");
161 writer.send_msg(serde_json::json!(response)).await?;
162 channel.close();
163 return Ok(());
164 }
165 Err(_) => {
166 channel.close();
167 return Ok(());
168 }
169 },
170 }
171 }
172}