Skip to content

Commit

Permalink
fix: reolad newest values after commit (update)
Browse files Browse the repository at this point in the history
this commit fixes a bug where new updates to search values
(packages + options) were not reflected at runtime and
required a restart.
this was due to the fact that at channelsearcher initialisation the
reader was dropped and an old version of the searcher store instead

since the searcher needs to be reinitialized for every query to
guarantee up-to-date results, this lead to a non-functional search when
the searcher is indexed first.

by storing the reader instead and reinitializing the searcher on every
request, new values are immediately reflected in search results
  • Loading branch information
PhilTaken committed Mar 10, 2024
1 parent aa7846b commit af48dca
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 38 deletions.
2 changes: 1 addition & 1 deletion src/nix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ pub struct NixPackage {
#[folder = "nix/"]
struct NixFiles;

#[tracing::instrument]
#[tracing::instrument(skip(flake))]
pub fn build_options_for_fcio_branch(
flake: &Flake,
) -> anyhow::Result<(
Expand Down
64 changes: 27 additions & 37 deletions src/search.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use anyhow::Context;
use itertools::Itertools;
use std::collections::HashMap;
use std::path::{Path, PathBuf};
Expand All @@ -17,7 +18,7 @@ struct SearcherInner {
schema: Schema,
index: tantivy::Index,
query_parser: QueryParser,
searcher: tantivy::Searcher,
reader: tantivy::IndexReader,
reference_field: Field,
}

Expand Down Expand Up @@ -108,14 +109,13 @@ impl Searcher for OptionsSearcher {
.try_into()
.unwrap();

let searcher = reader.searcher();
let query_parser = QueryParser::for_index(&index, vec![name, description, default]);

self.inner = Some(SearcherInner {
schema,
query_parser,
index,
searcher,
reader,
reference_field: original_name,
});

Expand Down Expand Up @@ -166,20 +166,19 @@ impl Searcher for OptionsSearcher {
#[tracing::instrument(skip(self))]
fn search_entries(&self, query: &str) -> Vec<&Self::Item> {
let Some(ref inner) = self.inner else {
debug!("searcher is not fully initialized, create the index first");
return Vec::new();
panic!("searcher is not fully initialized, create the index first");
};

let searcher = inner.reader.searcher();

let query = inner.query_parser.parse_query_lenient(query).0;
inner
.searcher
searcher
.search(&query, &TopDocs::with_limit(30))
.ok()
.map(|top_docs| {
top_docs
.into_iter()
.map(|(_score, doc_address)| {
let retrieved = inner.searcher.doc(doc_address).unwrap();
let retrieved = searcher.doc(doc_address).unwrap();
let name = retrieved
.get_first(inner.reference_field)
.expect("result has a value for name")
Expand Down Expand Up @@ -246,28 +245,24 @@ impl Searcher for PackagesSearcher {
schema_builder.add_text_field("long_description", TEXT);
let schema = schema_builder.build();

let index = match Index::create_in_dir(&self.index_path, schema.clone()) {
Ok(i) => i,
Err(tantivy::TantivyError::IndexAlreadyExists) => {
Index::open_in_dir(&self.index_path).unwrap()
}
Err(e) => return Err(anyhow::anyhow!(e)),
};
let index = Index::open_or_create(
tantivy::directory::MmapDirectory::open(&self.index_path).unwrap(),
schema.clone(),
)?;

let reader = index
.reader_builder()
.reload_policy(tantivy::ReloadPolicy::OnCommit)
.try_into()
.unwrap();

let searcher = reader.searcher();
let query_parser = QueryParser::for_index(&index, vec![name, description]);

self.inner = Some(SearcherInner {
schema,
query_parser,
index,
searcher,
reader,
reference_field: attribute_name,
});

Expand Down Expand Up @@ -323,16 +318,16 @@ impl Searcher for PackagesSearcher {
return Vec::new();
};

let searcher = inner.reader.searcher();
let query = inner.query_parser.parse_query_lenient(query).0;
inner
.searcher
searcher
.search(&query, &TopDocs::with_limit(30))
.ok()
.map(|top_docs| {
top_docs
.into_iter()
.map(|(_score, doc_address)| {
let retrieved = inner.searcher.doc(doc_address).unwrap();
let retrieved = searcher.doc(doc_address).unwrap();
let name = retrieved
.get_first(inner.reference_field)
.expect("result has a value for name")
Expand All @@ -357,9 +352,6 @@ struct ChannelSearcherInner {
impl ChannelSearcherInner {
/// attempt to load cached options
pub fn maybe_load(branch_path: &Path) -> Option<Self> {
let options_index_path = branch_path.join("tantivy");
let package_index_path = branch_path.join("tantivy_packages");

let options =
serde_json::from_str(&std::fs::read_to_string(branch_path.join("options.json")).ok()?)
.ok()?;
Expand All @@ -368,13 +360,7 @@ impl ChannelSearcherInner {
serde_json::from_str(&std::fs::read_to_string(branch_path.join("packages.json")).ok()?)
.ok()?;

let o_inner = OptionsSearcher::new_with_options(&options_index_path, options).ok()?;
let p_inner = PackagesSearcher::new_with_packages(&package_index_path, packages).ok()?;

Some(Self {
options: o_inner,
packages: p_inner,
})
Self::new_with_values(branch_path, options, packages)
}

pub fn new_with_values(
Expand Down Expand Up @@ -476,6 +462,11 @@ impl ChannelSearcher {
i.packages
.update_entries(packages)
.expect("could not update packages");
} else {
unreachable!(
"[{}] channel searcher is active but inner is not some",
f.branch
);
}
}
}
Expand Down Expand Up @@ -513,22 +504,21 @@ impl ChannelSearcher {
}
}

#[tracing::instrument]
#[tracing::instrument(skip(branch_path))]
pub fn update_file_cache(
branch_path: &Path,
flake: &Flake,
) -> anyhow::Result<(
HashMap<String, NaiveNixosOption>,
HashMap<String, NixPackage>,
)> {
anyhow::ensure!(branch_path.exists(), "branch path does not exist!");

let index_path = branch_path.join("tantivy");
let options_index_path = branch_path.join("tantivy");
let pkgs_index_path = branch_path.join("tantivy_packages");

std::fs::create_dir_all(index_path.clone()).expect("failed to create index path in state dir");
std::fs::create_dir_all(options_index_path.clone())
.context("failed to create options index path")?;
std::fs::create_dir_all(pkgs_index_path.clone())
.expect("failed to create index path in state dir");
.context("failed to create packages index path")?;

let (options, packages) = nix::build_options_for_fcio_branch(flake)?;
std::fs::write(
Expand Down

0 comments on commit af48dca

Please sign in to comment.