]> git.proxmox.com Git - proxmox-backup.git/blob - src/client/remote_chunk_reader.rs
switch from failure to anyhow
[proxmox-backup.git] / src / client / remote_chunk_reader.rs
1 use std::collections::HashMap;
2 use std::sync::Arc;
3
4 use anyhow::{Error};
5
6 use super::BackupReader;
7 use crate::backup::{ReadChunk, DataBlob, CryptConfig};
8 use crate::tools::runtime::block_on;
9
10 /// Read chunks from remote host using ``BackupReader``
11 pub struct RemoteChunkReader {
12 client: Arc<BackupReader>,
13 crypt_config: Option<Arc<CryptConfig>>,
14 cache_hint: HashMap<[u8; 32], usize>,
15 cache: HashMap<[u8; 32], Vec<u8>>,
16 }
17
18 impl RemoteChunkReader {
19
20 /// Create a new instance.
21 ///
22 /// Chunks listed in ``cache_hint`` are cached and kept in RAM.
23 pub fn new(
24 client: Arc<BackupReader>,
25 crypt_config: Option<Arc<CryptConfig>>,
26 cache_hint: HashMap<[u8; 32], usize>,
27 ) -> Self {
28
29 Self { client, crypt_config, cache_hint, cache: HashMap::new() }
30 }
31 }
32
33 impl ReadChunk for RemoteChunkReader {
34
35 fn read_raw_chunk(&mut self, digest:&[u8; 32]) -> Result<DataBlob, Error> {
36
37 let mut chunk_data = Vec::with_capacity(4*1024*1024);
38
39 //tokio::task::block_in_place(|| futures::executor::block_on(self.client.download_chunk(&digest, &mut chunk_data)))?;
40 block_on(async {
41 // download_chunk returns the writer back to us, but we need to return a 'static value
42 self.client
43 .download_chunk(&digest, &mut chunk_data)
44 .await
45 .map(drop)
46 })?;
47
48 let chunk = DataBlob::from_raw(chunk_data)?;
49 chunk.verify_crc()?;
50
51 Ok(chunk)
52 }
53
54 fn read_chunk(&mut self, digest:&[u8; 32]) -> Result<Vec<u8>, Error> {
55
56 if let Some(raw_data) = self.cache.get(digest) {
57 return Ok(raw_data.to_vec());
58 }
59
60 let chunk = self.read_raw_chunk(digest)?;
61
62 let raw_data = chunk.decode(self.crypt_config.as_ref().map(Arc::as_ref))?;
63
64 // fixme: verify digest?
65
66 let use_cache = self.cache_hint.contains_key(digest);
67 if use_cache {
68 self.cache.insert(*digest, raw_data.to_vec());
69 }
70
71 Ok(raw_data)
72 }
73
74 }