Spawn vs spawn_blocking tokio

We use the tokio runtime and embrace the thread per core model. So would this snippet be forbidden:

async fn pread(
        &self,
        file: Arc<File>,
        rsize: usize,
        offset: u64,
    ) -> std::result::Result<Buffer, Error> {
        let file = Arc::clone(&file);
        let mut buf = BufferPool::instance().get_buffer(rsize);
        let result = task::spawn(async move {
            let slice = buf.slice_mut(0, rsize).unwrap();
            let result = file.read_at(slice, offset);
            result
                .map(|_| buf)
                .map_err(|err| Error::new(err.to_string()))
        })
        .await
        .map_err(|err| Error::new(err.to_string()))?;
        return result;
    }

Should I prefer spawn_blocking to this? Thanks in advance.

1 Like

Assuming File is std::fs::File, then you'd want to use task::spawn_blocking, as read_at is a blocking operation. If you use spawn - which is allowed, just unwise - then whichever executor thread receives the spawned task will be blocked until it completes.

spawn_blocking dispatches jobs to a separate thread pool, which can block without blocking the executor.

1 Like