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 Endpoint, 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 let peer = quic_conn.peer_endpoint().ok();
63 loop {
64 let stream = quic_conn.accept_stream().await?;
65 let conn = framed(stream, codec.clone());
66 server
67 .task_group
68 .spawn(quic_handle_stream_task(server.clone(), conn, peer.clone()));
69 }
70}
71
72async fn quic_handle_stream_task(
73 server: Arc<Server>,
74 conn: FramedConn<JsonCodec>,
75 peer: Option<Endpoint>,
76) -> Result<()> {
77 if let Err(err) = handle_quic_stream(server, conn, peer).await {
78 error!("Handle QUIC stream: {err}");
79 }
80 Ok(())
81}
82
83async fn handle_quic_stream(
86 server: Arc<Server>,
87 mut conn: FramedConn<JsonCodec>,
88 peer: Option<Endpoint>,
89) -> Result<()> {
90 let msg = conn.recv_msg().await?;
91
92 let req = match sanity_check(msg) {
93 SanityCheckResult::NewReq(req) => req,
94 SanityCheckResult::ErrRes(res) => {
95 conn.send_msg(serde_json::json!(res)).await?;
96 return Ok(());
97 }
98 };
99
100 let is_pubsub = matches!(
106 server.resolve_handler(&req.srvc_name, &req.method_name, true),
107 Handler::Pubsub(_)
108 );
109
110 if is_pubsub {
111 return handle_quic_subscription(server, conn, req, peer).await;
112 }
113
114 let msg = serde_json::to_value(&req.msg).expect("serializable request");
115 let response = server.handle_request(None, msg).await;
116 debug!("--> {response}");
117 conn.send_msg(serde_json::json!(response)).await?;
118 Ok(())
119}
120
121async fn handle_quic_subscription(
124 server: Arc<Server>,
125 conn: FramedConn<JsonCodec>,
126 req: NewRequest,
127 peer: Option<Endpoint>,
128) -> Result<()> {
129 let (ch_tx, ch_rx) = async_channel::bounded(CHANNEL_SUBSCRIPTION_BUFFER_SIZE);
130 let channel = Channel::new(ch_tx, peer);
131
132 let method = match server.resolve_handler(&req.srvc_name, &req.method_name, true) {
133 Handler::Pubsub(m) => m,
134 _ => unreachable!("pubsub method presence checked by caller"),
135 };
136
137 let params = req.msg.params.unwrap_or(serde_json::json!(()));
138 let result = method(channel.clone(), req.msg.method, params).await;
139
140 let response = match result {
141 Ok(res) => message::Response {
142 result: Some(res),
143 id: Some(req.msg.id),
144 ..Default::default()
145 },
146 Err(err) => {
147 let mut conn = conn;
148 let response = err.to_response(Some(req.msg.id), None);
149 conn.send_msg(serde_json::json!(response)).await?;
150 return Ok(());
151 }
152 };
153
154 debug!("--> {response}");
155
156 let (mut reader, mut writer) = conn.split();
157 writer.send_msg(serde_json::json!(response)).await?;
158
159 let notification_encoder = server.config.notification_encoder;
160
161 loop {
162 match select(ch_rx.recv(), reader.recv_msg()).await {
163 Either::Left(nt) => {
164 let nt = nt?;
165 let notification = notification_encoder(nt);
166 debug!("--> {notification}");
167 writer.send_msg(serde_json::json!(notification)).await?;
168 }
169 Either::Right(msg) => match msg {
170 Ok(msg) => {
171 let response = server.handle_request(Some(channel.clone()), msg).await;
172 debug!("--> {response}");
173 writer.send_msg(serde_json::json!(response)).await?;
174 channel.close();
175 return Ok(());
176 }
177 Err(_) => {
178 channel.close();
179 return Ok(());
180 }
181 },
182 }
183 }
184}