Repository: meilisearch/meilisearch
File: index-scheduler/src/features.rs (Rust)

Code before:

    pub fn check_vector(&self) -> Result<()> {
        if self.runtime.vector_store {
            Ok(())
        } else {
            Err(FeatureNotEnabledError {
                disabled_action: "Passing `vector` as a query parameter",
                feature: "vector store",
                issue_link: "https://github.com/meilisearch/product/discussions/677",
            }
            .into())
        }
    }
}

impl FeatureData {
    pub fn new(env: &Env, instance_features: InstanceTogglableFeatures) -> Result<Self> {
        let mut wtxn = env.write_txn()?;
        let runtime_features = 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()?;

        Ok(Self { runtime: runtime_features })
    }

    pub fn put_runtime_features(
        &self,
        mut wtxn: RwTxn,
        features: RuntimeTogglableFeatures,
    ) -> Result<()> {
        self.runtime.put(&mut wtxn, EXPERIMENTAL_FEATURES, &features)?;
        wtxn.commit()?;
        Ok(())
    }

    fn runtime_features(&self, txn: RoTxn) -> Result<RuntimeTogglableFeatures> {
        Ok(self.runtime.get(&txn, EXPERIMENTAL_FEATURES)?.unwrap_or_default())
    }

    pub fn features(&self, txn: RoTxn) -> Result<RoFeatures> {
        RoFeatures::new(txn, self)
    }
}


Review comment (bug):
@Kerollmops, Setting `metrics: instance_features.metrics` to database is incorrect (maybe).

The reason is - let's say initially (when the server starts), at runtime level, metrics is `false` in DB, and, we pass `--experimental-enable-metrics` which gets persisted to DB. 

Now, if the user never updates the metrics feature using `PATCH /experimental-features`, the next time if the server runs without `--experimental-enable-metrics`, the metrics feature will be enabled (as it was persisted to DB the last time server had started), which is incorrect I feel.

Please correct me if I am wrong.
cc/ @curquiza 

Code after:
            .into())
        }
    }

    pub fn check_vector(&self) -> Result<()> {
        if self.runtime.vector_store {
            Ok(())
        } else {
            Err(FeatureNotEnabledError {
                disabled_action: "Passing `vector` as a query parameter",
                feature: "vector store",
                issue_link: "https://github.com/meilisearch/product/discussions/677",
            }
            .into())
        }
    }

    pub fn check_puffin(&self) -> Result<()> {
        if self.runtime.export_puffin_reports {
            Ok(())
        } else {
            Err(FeatureNotEnabledError {
                disabled_action: "Outputting Puffin reports to disk",
                feature: "export puffin reports",
                issue_link: "https://github.com/meilisearch/product/discussions/693",
            }
            .into())
        }
    }
}

impl FeatureData {
    pub fn new(env: &Env, instance_features: InstanceTogglableFeatures) -> Result<Self> {
        let mut wtxn = env.write_txn()?;
        let runtime_features_db = env.create_database(&mut wtxn, Some(EXPERIMENTAL_FEATURES))?;
        wtxn.commit()?;

        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(
        &self,
        mut wtxn: RwTxn,