@@ -3,16 +3,60 @@ pub mod ckb_indexer;
33pub mod ckb_light_client;
44
55use anyhow:: anyhow;
6- pub use ckb:: CkbRpcClient ;
7- pub use ckb_indexer:: IndexerRpcClient ;
6+ pub use ckb:: { CkbRpcAsyncClient , CkbRpcClient } ;
7+ pub use ckb_indexer:: { IndexerRpcAsyncClient , IndexerRpcClient } ;
88use ckb_jsonrpc_types:: { JsonBytes , ResponseFormat } ;
9- pub use ckb_light_client:: LightClientRpcClient ;
9+ pub use ckb_light_client:: { LightClientRpcAsyncClient , LightClientRpcClient } ;
1010
11- use std:: sync :: LazyLock ;
11+ use std:: { cell :: LazyCell , future :: Future } ;
1212use thiserror:: Error ;
1313
14- static RUNTIME : LazyLock < tokio:: runtime:: Runtime > =
15- LazyLock :: new ( || tokio:: runtime:: Runtime :: new ( ) . unwrap ( ) ) ;
14+ thread_local ! {
15+ pub static RUNTIME : LazyCell <tokio:: runtime:: Runtime > =
16+ LazyCell :: new( || tokio:: runtime:: Builder :: new_current_thread( ) . enable_all( ) . build( ) . unwrap( ) ) ;
17+ }
18+
19+ pub ( crate ) fn block_on < F : Send > ( future : impl Future < Output = F > + Send ) -> F {
20+ match tokio:: runtime:: Handle :: try_current ( ) {
21+ Ok ( h)
22+ if matches ! (
23+ h. runtime_flavor( ) ,
24+ tokio:: runtime:: RuntimeFlavor :: MultiThread
25+ ) =>
26+ {
27+ tokio:: task:: block_in_place ( || {
28+ h. block_on ( tokio:: time:: timeout (
29+ std:: time:: Duration :: from_secs ( 10 ) ,
30+ future,
31+ ) )
32+ . unwrap ( )
33+ } )
34+ }
35+ // if we on the current runtime, it must use another thread to poll this future,
36+ // can't block on current runtime, it will block current reactor to stop forever
37+ // in tokio runtime, this time will panic
38+ Ok ( _) => std:: thread:: scope ( |s| {
39+ s. spawn ( || {
40+ RUNTIME . with ( |rt| {
41+ rt. block_on ( tokio:: time:: timeout (
42+ std:: time:: Duration :: from_secs ( 10 ) ,
43+ future,
44+ ) )
45+ . unwrap ( )
46+ } )
47+ } )
48+ . join ( )
49+ . unwrap ( )
50+ } ) ,
51+ Err ( _) => RUNTIME . with ( |rt| {
52+ rt. block_on ( tokio:: time:: timeout (
53+ std:: time:: Duration :: from_secs ( 10 ) ,
54+ future,
55+ ) )
56+ . unwrap ( )
57+ } ) ,
58+ }
59+ }
1660
1761#[ derive( Error , Debug ) ]
1862pub enum RpcError {
@@ -38,8 +82,8 @@ macro_rules! jsonrpc {
3882 ) => (
3983 $( #[ $struct_attr] ) *
4084 pub struct $struct_name {
41- client: crate :: rpc:: RpcClient ,
42- id: std:: sync:: atomic:: AtomicU64 ,
85+ pub ( crate ) client: $ crate:: rpc:: RpcClient ,
86+ pub ( crate ) id: std:: sync:: atomic:: AtomicU64 ,
4387 }
4488
4589 impl Clone for $struct_name {
@@ -53,13 +97,13 @@ macro_rules! jsonrpc {
5397
5498 impl $struct_name {
5599 pub fn new( uri: & str ) -> Self {
56- $struct_name { id: 0 . into( ) , client: crate :: rpc:: RpcClient :: new( uri) , }
100+ $struct_name { id: 0 . into( ) , client: $ crate:: rpc:: RpcClient :: new( uri) , }
57101 }
58102
59103 pub fn post<PARAM , RET >( & self , method: & str , params: PARAM ) ->Result <RET , $crate:: rpc:: RpcError >
60104 where
61- PARAM : serde:: ser:: Serialize ,
62- RET : serde:: de:: DeserializeOwned ,
105+ PARAM : serde:: ser:: Serialize + Send + ' static ,
106+ RET : serde:: de:: DeserializeOwned + Send + ' static ,
63107 {
64108 let id = self . id. fetch_add( 1 , std:: sync:: atomic:: Ordering :: Relaxed ) ;
65109 let params_fn = || -> Result <_, _> {
@@ -73,7 +117,7 @@ macro_rules! jsonrpc {
73117 } ;
74118
75119 let task = self . client. post( params_fn) ;
76- crate :: rpc:: RUNTIME . block_on( task)
120+ $ crate:: rpc:: block_on( task)
77121
78122 }
79123
@@ -94,7 +138,7 @@ macro_rules! jsonrpc {
94138 } ;
95139
96140 let task = $selff. client. post( params_fn) ;
97- crate :: rpc:: RUNTIME . block_on( task)
141+ $ crate:: rpc:: block_on( task)
98142 }
99143 ) *
100144 }
@@ -113,8 +157,8 @@ macro_rules! jsonrpc_async {
113157 ) => (
114158 $( #[ $struct_attr] ) *
115159 pub struct $struct_name {
116- client: crate :: rpc:: RpcClient ,
117- id: std:: sync:: atomic:: AtomicU64 ,
160+ pub ( crate ) client: $ crate:: rpc:: RpcClient ,
161+ pub ( crate ) id: std:: sync:: atomic:: AtomicU64 ,
118162 }
119163
120164 impl Clone for $struct_name {
@@ -128,13 +172,13 @@ macro_rules! jsonrpc_async {
128172
129173 impl $struct_name {
130174 pub fn new( uri: & str ) -> Self {
131- $struct_name { id: 0 . into( ) , client: crate :: rpc:: RpcClient :: new( uri) , }
175+ $struct_name { id: 0 . into( ) , client: $ crate:: rpc:: RpcClient :: new( uri) , }
132176 }
133177
134- pub fn post<PARAM , RET >( & self , method: & str , params: PARAM ) ->impl std:: future:: Future <Output =Result <RET , $crate:: rpc:: RpcError >>
178+ pub fn post<PARAM , RET >( & self , method: & str , params: PARAM ) ->impl std:: future:: Future <Output =Result <RET , $crate:: rpc:: RpcError >> + Send + ' static
135179 where
136- PARAM : serde:: ser:: Serialize ,
137- RET : serde:: de:: DeserializeOwned ,
180+ PARAM : serde:: ser:: Serialize + Send + ' static ,
181+ RET : serde:: de:: DeserializeOwned + Send + ' static ,
138182 {
139183 let id = self . id. fetch_add( 1 , std:: sync:: atomic:: Ordering :: Relaxed ) ;
140184 let method = serde_json:: json!( method) ;
@@ -196,8 +240,8 @@ impl RpcClient {
196240 json_post_params : T ,
197241 ) -> impl std:: future:: Future < Output = Result < RET , crate :: rpc:: RpcError > >
198242 where
199- PARAM : serde:: ser:: Serialize ,
200- RET : serde:: de:: DeserializeOwned ,
243+ PARAM : serde:: ser:: Serialize + Send + ' static ,
244+ RET : serde:: de:: DeserializeOwned + Send + ' static ,
201245 T : FnOnce ( ) -> Result < PARAM , crate :: rpc:: RpcError > ,
202246 {
203247 let url = self . url . clone ( ) ;
0 commit comments