cfx_rpc_utils/helpers/
blocking_tasks.rs1use crate::error::EthApiError;
5use cfx_tasks::TaskSpawner;
6use futures::Future;
7use jsonrpsee::types::ErrorObjectOwned;
8use tokio::sync::oneshot;
9
10pub trait SpawnBlocking: Clone + Send + Sync + 'static {
12 fn io_task_spawner(&self) -> impl TaskSpawner;
16
17 fn spawn_blocking_io<F, R>(
23 &self, f: F,
24 ) -> impl Future<Output = Result<R, ErrorObjectOwned>> + Send
25 where
26 F: FnOnce(Self) -> Result<R, ErrorObjectOwned> + Send + 'static,
27 R: Send + 'static,
28 {
29 let (tx, rx) = oneshot::channel();
30 let this = self.clone();
31 self.io_task_spawner().spawn_blocking(Box::pin(async move {
32 let res = f(this);
33 let _ = tx.send(res);
34 }));
35
36 async move {
37 rx.await.map_err(|_| {
38 ErrorObjectOwned::from(EthApiError::InternalEthError)
39 })?
40 }
41 }
42}