mirror of
https://github.com/meilisearch/meilisearch.git
synced 2024-11-26 12:05:05 +08:00
Use RwLock to never persist cli state to db
This commit is contained in:
parent
d8c649b3cd
commit
dd619913da
@ -127,6 +127,8 @@ pub enum Error {
|
|||||||
Persist(#[from] tempfile::PersistError),
|
Persist(#[from] tempfile::PersistError),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
FeatureNotEnabled(#[from] FeatureNotEnabledError),
|
FeatureNotEnabled(#[from] FeatureNotEnabledError),
|
||||||
|
#[error("An unexpected error occurred when accessing the runtime features.")]
|
||||||
|
RuntimeFeatureToggleError,
|
||||||
|
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Anyhow(#[from] anyhow::Error),
|
Anyhow(#[from] anyhow::Error),
|
||||||
@ -186,6 +188,7 @@ impl Error {
|
|||||||
| Error::IoError(_)
|
| Error::IoError(_)
|
||||||
| Error::Persist(_)
|
| Error::Persist(_)
|
||||||
| Error::FeatureNotEnabled(_)
|
| Error::FeatureNotEnabled(_)
|
||||||
|
| Error::RuntimeFeatureToggleError
|
||||||
| Error::Anyhow(_) => true,
|
| Error::Anyhow(_) => true,
|
||||||
Error::CreateBatch(_)
|
Error::CreateBatch(_)
|
||||||
| Error::CorruptedTaskQueue
|
| Error::CorruptedTaskQueue
|
||||||
@ -232,6 +235,7 @@ impl ErrorCode for Error {
|
|||||||
Error::IoError(e) => e.error_code(),
|
Error::IoError(e) => e.error_code(),
|
||||||
Error::Persist(e) => e.error_code(),
|
Error::Persist(e) => e.error_code(),
|
||||||
Error::FeatureNotEnabled(_) => Code::FeatureNotEnabled,
|
Error::FeatureNotEnabled(_) => Code::FeatureNotEnabled,
|
||||||
|
Error::RuntimeFeatureToggleError => Code::Internal,
|
||||||
|
|
||||||
// Irrecoverable errors
|
// Irrecoverable errors
|
||||||
Error::Anyhow(_) => Code::Internal,
|
Error::Anyhow(_) => Code::Internal,
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
use meilisearch_types::features::{InstanceTogglableFeatures, RuntimeTogglableFeatures};
|
use meilisearch_types::features::{InstanceTogglableFeatures, RuntimeTogglableFeatures};
|
||||||
use meilisearch_types::heed::types::{SerdeJson, Str};
|
use meilisearch_types::heed::types::{SerdeJson, Str};
|
||||||
use meilisearch_types::heed::{Database, Env, RoTxn, RwTxn};
|
use meilisearch_types::heed::{Database, Env, RwTxn};
|
||||||
|
|
||||||
|
use crate::error::Error::RuntimeFeatureToggleError;
|
||||||
use crate::error::FeatureNotEnabledError;
|
use crate::error::FeatureNotEnabledError;
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
@ -9,7 +12,8 @@ const EXPERIMENTAL_FEATURES: &str = "experimental-features";
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct FeatureData {
|
pub(crate) struct FeatureData {
|
||||||
runtime: Database<Str, SerdeJson<RuntimeTogglableFeatures>>,
|
persisted: Database<Str, SerdeJson<RuntimeTogglableFeatures>>,
|
||||||
|
runtime: Arc<RwLock<RuntimeTogglableFeatures>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
@ -18,8 +22,8 @@ pub struct RoFeatures {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RoFeatures {
|
impl RoFeatures {
|
||||||
fn new(txn: RoTxn<'_>, data: &FeatureData) -> Result<Self> {
|
fn new(data: &FeatureData) -> Result<Self> {
|
||||||
let runtime = data.runtime_features(txn)?;
|
let runtime = data.runtime_features()?;
|
||||||
Ok(Self { runtime })
|
Ok(Self { runtime })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,13 +87,18 @@ impl RoFeatures {
|
|||||||
impl FeatureData {
|
impl FeatureData {
|
||||||
pub fn new(env: &Env, instance_features: InstanceTogglableFeatures) -> Result<Self> {
|
pub fn new(env: &Env, instance_features: InstanceTogglableFeatures) -> Result<Self> {
|
||||||
let mut wtxn = env.write_txn()?;
|
let mut wtxn = env.write_txn()?;
|
||||||
let runtime_features = env.create_database(&mut wtxn, Some(EXPERIMENTAL_FEATURES))?;
|
let runtime_features_db = env.create_database(&mut wtxn, Some(EXPERIMENTAL_FEATURES))?;
|
||||||
let default_features =
|
|
||||||
RuntimeTogglableFeatures { metrics: instance_features.metrics, ..Default::default() };
|
|
||||||
runtime_features.put(&mut wtxn, EXPERIMENTAL_FEATURES, &default_features)?;
|
|
||||||
wtxn.commit()?;
|
wtxn.commit()?;
|
||||||
|
|
||||||
Ok(Self { runtime: runtime_features })
|
let txn = env.read_txn()?;
|
||||||
|
let persisted_features: RuntimeTogglableFeatures =
|
||||||
|
runtime_features_db.get(&txn, EXPERIMENTAL_FEATURES)?.unwrap_or_default();
|
||||||
|
let runtime = Arc::new(RwLock::new(RuntimeTogglableFeatures {
|
||||||
|
metrics: instance_features.metrics || persisted_features.metrics,
|
||||||
|
..persisted_features
|
||||||
|
}));
|
||||||
|
|
||||||
|
Ok(Self { persisted: runtime_features_db, runtime })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn put_runtime_features(
|
pub fn put_runtime_features(
|
||||||
@ -97,16 +106,19 @@ impl FeatureData {
|
|||||||
mut wtxn: RwTxn,
|
mut wtxn: RwTxn,
|
||||||
features: RuntimeTogglableFeatures,
|
features: RuntimeTogglableFeatures,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.runtime.put(&mut wtxn, EXPERIMENTAL_FEATURES, &features)?;
|
self.persisted.put(&mut wtxn, EXPERIMENTAL_FEATURES, &features)?;
|
||||||
wtxn.commit()?;
|
wtxn.commit()?;
|
||||||
|
|
||||||
|
let mut toggled_features = self.runtime.write().map_err(|_| RuntimeFeatureToggleError)?;
|
||||||
|
*toggled_features = features;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn runtime_features(&self, txn: RoTxn) -> Result<RuntimeTogglableFeatures> {
|
fn runtime_features(&self) -> Result<RuntimeTogglableFeatures> {
|
||||||
Ok(self.runtime.get(&txn, EXPERIMENTAL_FEATURES)?.unwrap_or_default())
|
Ok(*self.runtime.read().map_err(|_| RuntimeFeatureToggleError)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn features(&self, txn: RoTxn) -> Result<RoFeatures> {
|
pub fn features(&self) -> Result<RoFeatures> {
|
||||||
RoFeatures::new(txn, self)
|
RoFeatures::new(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1300,8 +1300,7 @@ impl IndexScheduler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn features(&self) -> Result<RoFeatures> {
|
pub fn features(&self) -> Result<RoFeatures> {
|
||||||
let rtxn = self.read_txn()?;
|
self.features.features()
|
||||||
self.features.features(rtxn)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn put_runtime_features(&self, features: RuntimeTogglableFeatures) -> Result<()> {
|
pub fn put_runtime_features(&self, features: RuntimeTogglableFeatures) -> Result<()> {
|
||||||
|
@ -126,6 +126,14 @@ async fn experimental_feature_metrics() {
|
|||||||
let (response, code) = server.get_metrics().await;
|
let (response, code) = server.get_metrics().await;
|
||||||
meili_snap::snapshot!(code, @"200 OK");
|
meili_snap::snapshot!(code, @"200 OK");
|
||||||
meili_snap::snapshot!(response, @"null");
|
meili_snap::snapshot!(response, @"null");
|
||||||
|
|
||||||
|
// startup without flag respects persisted metrics value
|
||||||
|
let disable_metrics =
|
||||||
|
Opt { experimental_enable_metrics: false, ..default_settings(dir.path()) };
|
||||||
|
let server_no_flag = Server::new_with_options(disable_metrics).await.unwrap();
|
||||||
|
let (response, code) = server_no_flag.get_metrics().await;
|
||||||
|
meili_snap::snapshot!(code, @"200 OK");
|
||||||
|
meili_snap::snapshot!(response, @"null");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
|
Loading…
Reference in New Issue
Block a user