2020-04-08 20:13:45 +08:00
|
|
|
use std::{env, thread};
|
2019-11-22 02:15:33 +08:00
|
|
|
|
2019-10-31 22:09:23 +08:00
|
|
|
use log::info;
|
|
|
|
use main_error::MainError;
|
2019-11-20 00:09:06 +08:00
|
|
|
use structopt::StructOpt;
|
2020-04-07 23:47:35 +08:00
|
|
|
use actix_web::middleware::Logger;
|
2020-04-09 16:39:34 +08:00
|
|
|
use actix_web::{web, HttpServer, App};
|
2019-11-26 18:06:55 +08:00
|
|
|
use meilisearch_http::data::Data;
|
|
|
|
use meilisearch_http::option::Opt;
|
|
|
|
use meilisearch_http::routes;
|
2020-04-08 20:13:45 +08:00
|
|
|
use meilisearch_http::routes::index_update_callback;
|
2019-10-31 22:09:23 +08:00
|
|
|
|
2019-11-22 02:15:33 +08:00
|
|
|
mod analytics;
|
|
|
|
|
2019-11-25 21:51:47 +08:00
|
|
|
#[cfg(target_os = "linux")]
|
2019-10-31 22:09:23 +08:00
|
|
|
#[global_allocator]
|
|
|
|
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
|
|
|
|
|
2020-04-07 23:47:35 +08:00
|
|
|
#[tokio::main]
|
|
|
|
async fn main() -> Result<(), MainError> {
|
2019-11-20 00:09:06 +08:00
|
|
|
let opt = Opt::from_args();
|
2020-04-07 23:47:35 +08:00
|
|
|
let local = tokio::task::LocalSet::new();
|
|
|
|
let _sys = actix_rt::System::run_in_tokio("server", &local);
|
2019-11-16 00:33:06 +08:00
|
|
|
|
2020-02-06 22:42:35 +08:00
|
|
|
match opt.env.as_ref() {
|
|
|
|
"production" => {
|
|
|
|
if opt.master_key.is_none() {
|
2020-02-27 01:49:17 +08:00
|
|
|
return Err(
|
|
|
|
"In production mode, the environment variable MEILI_MASTER_KEY is mandatory"
|
|
|
|
.into(),
|
|
|
|
);
|
2020-02-06 22:42:35 +08:00
|
|
|
}
|
2020-04-07 23:47:35 +08:00
|
|
|
},
|
2020-02-06 22:42:35 +08:00
|
|
|
"development" => {
|
|
|
|
env_logger::from_env(env_logger::Env::default().default_filter_or("info")).init();
|
2020-02-27 01:49:17 +08:00
|
|
|
}
|
2020-02-06 22:42:35 +08:00
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
|
|
|
|
if !opt.no_analytics {
|
2020-02-13 17:25:37 +08:00
|
|
|
thread::spawn(analytics::analytics_sender);
|
2019-11-22 02:15:33 +08:00
|
|
|
}
|
|
|
|
|
2020-02-06 22:42:35 +08:00
|
|
|
let data = Data::new(opt.clone());
|
|
|
|
|
2019-11-16 00:33:06 +08:00
|
|
|
let data_cloned = data.clone();
|
|
|
|
data.db.set_update_callback(Box::new(move |name, status| {
|
2020-04-08 20:13:45 +08:00
|
|
|
index_update_callback(name, &data_cloned, status);
|
2019-11-16 00:33:06 +08:00
|
|
|
}));
|
|
|
|
|
2020-02-06 22:42:35 +08:00
|
|
|
print_launch_resume(&opt, &data);
|
|
|
|
|
2020-04-07 23:47:35 +08:00
|
|
|
HttpServer::new(move ||
|
|
|
|
App::new()
|
|
|
|
.wrap(Logger::default())
|
|
|
|
.app_data(web::Data::new(data.clone()))
|
2020-04-08 00:30:38 +08:00
|
|
|
.service(routes::load_html)
|
|
|
|
.service(routes::load_css)
|
2020-04-08 20:13:45 +08:00
|
|
|
.service(routes::index::list_indexes)
|
|
|
|
.service(routes::index::get_index)
|
|
|
|
.service(routes::index::create_index)
|
|
|
|
.service(routes::index::update_index)
|
|
|
|
.service(routes::index::delete_index)
|
2020-04-09 16:39:34 +08:00
|
|
|
.service(routes::index::get_update_status)
|
|
|
|
.service(routes::index::get_all_updates_status)
|
2020-04-08 20:13:45 +08:00
|
|
|
.service(routes::search::search_with_url_query)
|
|
|
|
.service(routes::search::search_multi_index)
|
2020-04-07 23:47:35 +08:00
|
|
|
.service(routes::document::get_document)
|
|
|
|
.service(routes::document::delete_document)
|
|
|
|
.service(routes::document::get_all_documents)
|
|
|
|
.service(routes::document::add_documents)
|
|
|
|
.service(routes::document::update_documents)
|
|
|
|
.service(routes::document::delete_documents)
|
|
|
|
.service(routes::document::clear_all_documents)
|
2020-04-10 16:13:08 +08:00
|
|
|
.service(routes::setting::update_all)
|
|
|
|
.service(routes::setting::get_all)
|
|
|
|
.service(routes::setting::delete_all)
|
|
|
|
.service(routes::setting::get_rules)
|
|
|
|
.service(routes::setting::update_rules)
|
|
|
|
.service(routes::setting::delete_rules)
|
|
|
|
.service(routes::setting::get_distinct)
|
|
|
|
.service(routes::setting::update_distinct)
|
|
|
|
.service(routes::setting::delete_distinct)
|
|
|
|
.service(routes::setting::get_searchable)
|
|
|
|
.service(routes::setting::update_searchable)
|
|
|
|
.service(routes::setting::delete_searchable)
|
|
|
|
.service(routes::setting::get_displayed)
|
|
|
|
.service(routes::setting::update_displayed)
|
|
|
|
.service(routes::setting::delete_displayed)
|
|
|
|
.service(routes::setting::get_accept_new_fields)
|
|
|
|
.service(routes::setting::update_accept_new_fields)
|
2020-04-08 01:10:32 +08:00
|
|
|
.service(routes::key::list)
|
2020-04-08 20:13:45 +08:00
|
|
|
.service(routes::stats::index_stats)
|
|
|
|
.service(routes::stats::get_stats)
|
|
|
|
.service(routes::stats::get_version)
|
|
|
|
.service(routes::stats::get_sys_info)
|
|
|
|
.service(routes::stats::get_sys_info_pretty)
|
2020-04-08 00:30:38 +08:00
|
|
|
.service(routes::health::get_health)
|
|
|
|
.service(routes::health::change_healthyness)
|
2020-04-07 23:47:35 +08:00
|
|
|
)
|
|
|
|
.bind(opt.http_addr)?
|
|
|
|
.run()
|
|
|
|
.await?;
|
2019-10-31 22:09:23 +08:00
|
|
|
|
|
|
|
Ok(())
|
2019-10-31 22:00:36 +08:00
|
|
|
}
|
2020-02-06 22:42:35 +08:00
|
|
|
|
|
|
|
pub fn print_launch_resume(opt: &Opt, data: &Data) {
|
|
|
|
let ascii_name = r#"
|
|
|
|
888b d888 d8b 888 d8b .d8888b. 888
|
|
|
|
8888b d8888 Y8P 888 Y8P d88P Y88b 888
|
|
|
|
88888b.d88888 888 Y88b. 888
|
|
|
|
888Y88888P888 .d88b. 888 888 888 "Y888b. .d88b. 8888b. 888d888 .d8888b 88888b.
|
|
|
|
888 Y888P 888 d8P Y8b 888 888 888 "Y88b. d8P Y8b "88b 888P" d88P" 888 "88b
|
|
|
|
888 Y8P 888 88888888 888 888 888 "888 88888888 .d888888 888 888 888 888
|
|
|
|
888 " 888 Y8b. 888 888 888 Y88b d88P Y8b. 888 888 888 Y88b. 888 888
|
|
|
|
888 888 "Y8888 888 888 888 "Y8888P" "Y8888 "Y888888 888 "Y8888P 888 888
|
|
|
|
"#;
|
|
|
|
|
2020-04-07 23:47:35 +08:00
|
|
|
info!("{}", ascii_name);
|
2020-02-06 22:42:35 +08:00
|
|
|
|
|
|
|
info!("Database path: {:?}", opt.db_path);
|
|
|
|
info!("Start server on: {:?}", opt.http_addr);
|
|
|
|
info!("Environment: {:?}", opt.env);
|
|
|
|
info!("Commit SHA: {:?}", env!("VERGEN_SHA").to_string());
|
2020-02-27 01:49:17 +08:00
|
|
|
info!(
|
|
|
|
"Build date: {:?}",
|
|
|
|
env!("VERGEN_BUILD_TIMESTAMP").to_string()
|
|
|
|
);
|
|
|
|
info!(
|
|
|
|
"Package version: {:?}",
|
|
|
|
env!("CARGO_PKG_VERSION").to_string()
|
|
|
|
);
|
2020-02-06 22:42:35 +08:00
|
|
|
|
|
|
|
if let Some(master_key) = &data.api_keys.master {
|
|
|
|
info!("Master Key: {:?}", master_key);
|
|
|
|
|
|
|
|
if let Some(private_key) = &data.api_keys.private {
|
|
|
|
info!("Private Key: {:?}", private_key);
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(public_key) = &data.api_keys.public {
|
|
|
|
info!("Public Key: {:?}", public_key);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
info!("No master key found; The server will have no securities.\
|
|
|
|
If you need some protection in development mode, please export a key. export MEILI_MASTER_KEY=xxx");
|
|
|
|
}
|
|
|
|
|
|
|
|
info!("If you need extra information; Please refer to the documentation: http://docs.meilisearch.com");
|
|
|
|
info!("If you want to support us or help us; Please consult our Github repo: http://github.com/meilisearch/meilisearch");
|
|
|
|
info!("If you want to contact us; Please chat with us on http://meilisearch.com or by email to bonjour@meilisearch.com");
|
|
|
|
}
|