Files
stripstream-librarian/apps/indexer/src/main.rs
Froidefond Julien 389d71b42f refactor: replace Meilisearch with PostgreSQL full-text search
Remove Meilisearch dependency entirely. Search is now handled by
PostgreSQL ILIKE with pg_trgm indexes, joining series_metadata for
series-level authors. No external search engine needed.

- Replace search.rs Meilisearch HTTP calls with PostgreSQL queries
- Remove meili.rs from indexer, sync_meili call from job pipeline
- Remove MEILI_URL/MEILI_MASTER_KEY from config, state, env files
- Remove meilisearch service from docker-compose.yml
- Add migration 0027: drop sync_metadata, enable pg_trgm, add indexes
- Remove search resync button/endpoint (no longer needed)
- Update all documentation (CLAUDE.md, README.md, AGENTS.md, PLAN.md)

API contract unchanged — same SearchResponse shape returned.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 10:59:25 +01:00

47 lines
1.5 KiB
Rust

use axum::{routing::get, Router};
use indexer::{api, AppState};
use sqlx::postgres::PgPoolOptions;
use stripstream_core::config::IndexerConfig;
use tracing::info;
fn main() -> anyhow::Result<()> {
// Limit blocking thread pool to 8 threads (default 512).
// Each spawn_blocking call (archive extraction, image save) gets a thread.
// With thousands of books, unlimited threads cause OOM via stack memory (~8MB each).
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.max_blocking_threads(8)
.build()?;
runtime.block_on(async_main())
}
async fn async_main() -> anyhow::Result<()> {
tracing_subscriber::fmt()
.with_env_filter(
std::env::var("RUST_LOG").unwrap_or_else(|_| {
"indexer=info,axum=info,scan=info,extraction=info,thumbnail=warn,watcher=info".to_string()
}),
)
.init();
let config = IndexerConfig::from_env()?;
let pool = PgPoolOptions::new()
.max_connections(20)
.connect(&config.database_url)
.await?;
let state = AppState { pool };
tokio::spawn(indexer::worker::run_worker(state.clone(), config.scan_interval_seconds));
let app = Router::new()
.route("/health", get(api::health))
.route("/ready", get(api::ready))
.with_state(state.clone());
let listener = tokio::net::TcpListener::bind(&config.listen_addr).await?;
info!(addr = %config.listen_addr, "indexer listening");
axum::serve(listener, app).await?;
Ok(())
}