feat: 支持前端编辑、提交 Config (#370)
This commit is contained in:
@@ -10,16 +10,19 @@ pub struct VersionedCache<T> {
|
||||
inner: ArcSwap<T>,
|
||||
version: AtomicU64,
|
||||
builder: fn(&Config) -> Result<T>,
|
||||
mutex: parking_lot::Mutex<()>,
|
||||
}
|
||||
|
||||
impl<T> VersionedCache<T> {
|
||||
pub fn new(builder: fn(&Config) -> Result<T>) -> Result<Self> {
|
||||
let current_config = VersionedConfig::get().load();
|
||||
let current_version = current_config.version;
|
||||
let initial_value = builder(¤t_config)?;
|
||||
Ok(Self {
|
||||
inner: ArcSwap::from_pointee(initial_value),
|
||||
version: AtomicU64::new(0),
|
||||
version: AtomicU64::new(current_version),
|
||||
builder,
|
||||
mutex: parking_lot::Mutex::new(()),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -28,21 +31,23 @@ impl<T> VersionedCache<T> {
|
||||
self.inner.load()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn load_full(&self) -> Arc<T> {
|
||||
self.reload_if_needed();
|
||||
self.inner.load_full()
|
||||
}
|
||||
|
||||
fn reload_if_needed(&self) {
|
||||
let current_version = VersionedConfig::get().version();
|
||||
let cached_version = self.version.load(Ordering::Acquire);
|
||||
|
||||
if current_version != cached_version {
|
||||
let current_config = VersionedConfig::get().load();
|
||||
if let Ok(new_value) = (self.builder)(¤t_config) {
|
||||
self.inner.store(Arc::new(new_value));
|
||||
self.version.store(current_version, Ordering::Release);
|
||||
let current_config = VersionedConfig::get().load();
|
||||
let current_version = current_config.version;
|
||||
let version = self.version.load(Ordering::Relaxed);
|
||||
if version < current_version {
|
||||
let _lock = self.mutex.lock();
|
||||
if self.version.load(Ordering::Relaxed) >= current_version {
|
||||
return;
|
||||
}
|
||||
match (self.builder)(¤t_config) {
|
||||
Err(e) => {
|
||||
error!("Failed to rebuild versioned cache: {:?}", e);
|
||||
}
|
||||
Ok(new_value) => {
|
||||
self.inner.store(Arc::new(new_value));
|
||||
self.version.store(current_version, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user