Extract Searcher::open_or_recreate() from main()
This commit is contained in:
parent
43f32d30cb
commit
09d9164a1c
@ -1,15 +1,17 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
config::SearchTokenizerConfig, instance::Instance, posts::Post, schema::posts,
|
config::SearchTokenizerConfig, instance::Instance, posts::Post, schema::posts,
|
||||||
search::query::PlumeQuery, tags::Tag, Connection, Result,
|
search::query::PlumeQuery, tags::Tag, Connection, Error, Result, CONFIG,
|
||||||
};
|
};
|
||||||
use chrono::Datelike;
|
use chrono::{Datelike, Utc};
|
||||||
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl};
|
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use std::fs;
|
||||||
use std::{cmp, fs::create_dir_all, io, path::Path, sync::Mutex};
|
use std::{cmp, fs::create_dir_all, io, path::Path, sync::Mutex};
|
||||||
use tantivy::{
|
use tantivy::{
|
||||||
collector::TopDocs, directory::MmapDirectory, schema::*, Index, IndexReader, IndexWriter,
|
collector::TopDocs, directory::MmapDirectory, schema::*, Index, IndexReader, IndexWriter,
|
||||||
ReloadPolicy, TantivyError, Term,
|
ReloadPolicy, TantivyError, Term,
|
||||||
};
|
};
|
||||||
|
use tracing::warn;
|
||||||
use whatlang::{detect as detect_lang, Lang};
|
use whatlang::{detect as detect_lang, Lang};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -67,6 +69,62 @@ impl Searcher {
|
|||||||
schema_builder.build()
|
schema_builder.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn open_or_recreate() -> Self {
|
||||||
|
let mut open_searcher = Self::open(&CONFIG.search_index, &CONFIG.search_tokenizers);
|
||||||
|
if let Err(Error::Search(SearcherError::InvalidIndexDataError)) = open_searcher {
|
||||||
|
if Self::create(&CONFIG.search_index, &CONFIG.search_tokenizers).is_err() {
|
||||||
|
let current_path = Path::new(&CONFIG.search_index);
|
||||||
|
let backup_path = format!("{}.{}", ¤t_path.display(), Utc::now().timestamp());
|
||||||
|
let backup_path = Path::new(&backup_path);
|
||||||
|
fs::rename(current_path, backup_path)
|
||||||
|
.expect("main: error on backing up search index directory for recreating");
|
||||||
|
if Self::create(&CONFIG.search_index, &CONFIG.search_tokenizers).is_ok() {
|
||||||
|
if fs::remove_dir_all(backup_path).is_err() {
|
||||||
|
warn!(
|
||||||
|
"error on removing backup directory: {}. it remains",
|
||||||
|
backup_path.display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("main: error on recreating search index in new index format. remove search index and run `plm search init` manually");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open_searcher = Self::open(&CONFIG.search_index, &CONFIG.search_tokenizers);
|
||||||
|
}
|
||||||
|
#[allow(clippy::match_wild_err_arm)]
|
||||||
|
let searcher = match open_searcher {
|
||||||
|
Err(Error::Search(e)) => match e {
|
||||||
|
SearcherError::WriteLockAcquisitionError => panic!(
|
||||||
|
r#"
|
||||||
|
Your search index is locked. Plume can't start. To fix this issue
|
||||||
|
make sure no other Plume instance is started, and run:
|
||||||
|
|
||||||
|
plm search unlock
|
||||||
|
|
||||||
|
Then try to restart Plume.
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
SearcherError::IndexOpeningError => panic!(
|
||||||
|
r#"
|
||||||
|
Plume was unable to open the search index. If you created the index
|
||||||
|
before, make sure to run Plume in the same directory it was created in, or
|
||||||
|
to set SEARCH_INDEX accordingly. If you did not yet create the search
|
||||||
|
index, run this command:
|
||||||
|
|
||||||
|
plm search init
|
||||||
|
|
||||||
|
Then try to restart Plume
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
e => Err(e).unwrap(),
|
||||||
|
},
|
||||||
|
Err(_) => panic!("Unexpected error while opening search index"),
|
||||||
|
Ok(s) => s,
|
||||||
|
};
|
||||||
|
|
||||||
|
searcher
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create(path: &dyn AsRef<Path>, tokenizers: &SearchTokenizerConfig) -> Result<Self> {
|
pub fn create(path: &dyn AsRef<Path>, tokenizers: &SearchTokenizerConfig) -> Result<Self> {
|
||||||
let schema = Self::schema();
|
let schema = Self::schema();
|
||||||
|
|
||||||
|
61
src/main.rs
61
src/main.rs
@ -10,20 +10,17 @@ extern crate serde_json;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate validator_derive;
|
extern crate validator_derive;
|
||||||
|
|
||||||
use chrono::Utc;
|
|
||||||
use clap::App;
|
use clap::App;
|
||||||
use diesel::r2d2::ConnectionManager;
|
use diesel::r2d2::ConnectionManager;
|
||||||
use plume_models::{
|
use plume_models::{
|
||||||
db_conn::{DbPool, PragmaForeignKey},
|
db_conn::{DbPool, PragmaForeignKey},
|
||||||
instance::Instance,
|
instance::Instance,
|
||||||
migrations::IMPORTED_MIGRATIONS,
|
migrations::IMPORTED_MIGRATIONS,
|
||||||
search::{Searcher as UnmanagedSearcher, SearcherError},
|
search::Searcher as UnmanagedSearcher,
|
||||||
Connection, Error, CONFIG,
|
Connection, CONFIG,
|
||||||
};
|
};
|
||||||
use rocket_csrf::CsrfFairingBuilder;
|
use rocket_csrf::CsrfFairingBuilder;
|
||||||
use scheduled_thread_pool::ScheduledThreadPool;
|
use scheduled_thread_pool::ScheduledThreadPool;
|
||||||
use std::fs;
|
|
||||||
use std::path::Path;
|
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@ -103,59 +100,7 @@ Then try to restart Plume.
|
|||||||
}
|
}
|
||||||
let workpool = ScheduledThreadPool::with_name("worker {}", num_cpus::get());
|
let workpool = ScheduledThreadPool::with_name("worker {}", num_cpus::get());
|
||||||
// we want a fast exit here, so
|
// we want a fast exit here, so
|
||||||
let mut open_searcher =
|
let searcher = Arc::new(UnmanagedSearcher::open_or_recreate());
|
||||||
UnmanagedSearcher::open(&CONFIG.search_index, &CONFIG.search_tokenizers);
|
|
||||||
if let Err(Error::Search(SearcherError::InvalidIndexDataError)) = open_searcher {
|
|
||||||
if UnmanagedSearcher::create(&CONFIG.search_index, &CONFIG.search_tokenizers).is_err() {
|
|
||||||
let current_path = Path::new(&CONFIG.search_index);
|
|
||||||
let backup_path = format!("{}.{}", ¤t_path.display(), Utc::now().timestamp());
|
|
||||||
let backup_path = Path::new(&backup_path);
|
|
||||||
fs::rename(current_path, backup_path)
|
|
||||||
.expect("main: error on backing up search index directory for recreating");
|
|
||||||
if UnmanagedSearcher::create(&CONFIG.search_index, &CONFIG.search_tokenizers).is_ok() {
|
|
||||||
if fs::remove_dir_all(backup_path).is_err() {
|
|
||||||
warn!(
|
|
||||||
"error on removing backup directory: {}. it remains",
|
|
||||||
backup_path.display()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
panic!("main: error on recreating search index in new index format. remove search index and run `plm search init` manually");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
open_searcher = UnmanagedSearcher::open(&CONFIG.search_index, &CONFIG.search_tokenizers);
|
|
||||||
}
|
|
||||||
#[allow(clippy::match_wild_err_arm)]
|
|
||||||
let searcher = match open_searcher {
|
|
||||||
Err(Error::Search(e)) => match e {
|
|
||||||
SearcherError::WriteLockAcquisitionError => panic!(
|
|
||||||
r#"
|
|
||||||
Your search index is locked. Plume can't start. To fix this issue
|
|
||||||
make sure no other Plume instance is started, and run:
|
|
||||||
|
|
||||||
plm search unlock
|
|
||||||
|
|
||||||
Then try to restart Plume.
|
|
||||||
"#
|
|
||||||
),
|
|
||||||
SearcherError::IndexOpeningError => panic!(
|
|
||||||
r#"
|
|
||||||
Plume was unable to open the search index. If you created the index
|
|
||||||
before, make sure to run Plume in the same directory it was created in, or
|
|
||||||
to set SEARCH_INDEX accordingly. If you did not yet create the search
|
|
||||||
index, run this command:
|
|
||||||
|
|
||||||
plm search init
|
|
||||||
|
|
||||||
Then try to restart Plume
|
|
||||||
"#
|
|
||||||
),
|
|
||||||
e => Err(e).unwrap(),
|
|
||||||
},
|
|
||||||
Err(_) => panic!("Unexpected error while opening search index"),
|
|
||||||
Ok(s) => Arc::new(s),
|
|
||||||
};
|
|
||||||
|
|
||||||
let commiter = searcher.clone();
|
let commiter = searcher.clone();
|
||||||
workpool.execute_with_fixed_delay(
|
workpool.execute_with_fixed_delay(
|
||||||
Duration::from_secs(5),
|
Duration::from_secs(5),
|
||||||
|
Loading…
Reference in New Issue
Block a user