Spaces:
Build error
Build error
File size: 2,713 Bytes
84d2a97 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
use std::ops::Deref;
use std::sync::Arc;
use atomic_refcell::AtomicRefCell;
use common::types::PointOffsetType;
use crate::payload_storage::payload_storage_enum::PayloadStorageEnum;
use crate::payload_storage::PayloadStorage;
use crate::types::{OwnedPayloadRef, Payload};
#[derive(Clone)]
pub struct PayloadProvider {
payload_storage: Arc<AtomicRefCell<PayloadStorageEnum>>,
empty_payload: Payload,
}
impl PayloadProvider {
pub fn new(payload_storage: Arc<AtomicRefCell<PayloadStorageEnum>>) -> Self {
Self {
payload_storage,
empty_payload: Default::default(),
}
}
pub fn with_payload<F, G>(&self, point_id: PointOffsetType, callback: F) -> G
where
F: FnOnce(OwnedPayloadRef) -> G,
{
let payload_storage_guard = self.payload_storage.borrow();
let payload_ptr_opt = match payload_storage_guard.deref() {
#[cfg(feature = "testing")]
PayloadStorageEnum::InMemoryPayloadStorage(s) => {
s.payload_ptr(point_id).map(OwnedPayloadRef::from)
}
PayloadStorageEnum::SimplePayloadStorage(s) => {
s.payload_ptr(point_id).map(OwnedPayloadRef::from)
}
// Warn: Possible panic here
// Currently, it is possible that `read_payload` fails with Err,
// but it seems like a very rare possibility which might only happen
// if something is wrong with disk or storage is corrupted.
//
// In both cases it means that service can't be of use any longer.
// It is as good as dead. Therefore it is tolerable to just panic here.
// Downside is - API user won't be notified of the failure.
// It will just timeout.
//
// The alternative:
// Rewrite condition checking code to support error reporting.
// Which may lead to slowdown and assumes a lot of changes.
PayloadStorageEnum::OnDiskPayloadStorage(s) => s
.read_payload(point_id)
.unwrap_or_else(|err| panic!("Payload storage is corrupted: {err}"))
.map(OwnedPayloadRef::from),
PayloadStorageEnum::MmapPayloadStorage(s) => {
let payload = s
.get(point_id)
.unwrap_or_else(|err| panic!("Payload storage is corrupted: {err}"));
Some(OwnedPayloadRef::from(payload))
}
};
let payload = if let Some(payload_ptr) = payload_ptr_opt {
payload_ptr
} else {
OwnedPayloadRef::from(&self.empty_payload)
};
callback(payload)
}
}
|