mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-07-03 04:19:32 +00:00
The indexer's storage location was the `home` field of IndexerConfig, used only to derive the RocksDB dir. Defaulting to "." meant it landed in the process CWD — fine for the standalone service, but wrong when the indexer runs embedded in a logos_host subprocess (RocksDB ended up in an arbitrary/unwritable dir). Storage location is an operational concern the host should own, not something baked into a user-editable config. Remove `home` from IndexerConfig and pass the storage directory explicitly: - core: `IndexerCore::new(config, storage_dir)` derives `<storage_dir>/rocksdb`. - ffi: `start_indexer(runtime, config_path, storage_dir)`; null/empty storage_dir falls back to ".". Lets a host (e.g. a Logos module's instance persistence path) own where state lives. - service: `run_server(config, storage_dir, port)` + a `--data-dir` flag (default ".") on the binary, preserving current behaviour. - drop `home` from the committed indexer config JSONs and the test fixtures. BREAKING CHANGE: `start_indexer` gains a `storage_dir` parameter and IndexerConfig no longer has a `home` field.
98 lines
2.4 KiB
Rust
98 lines
2.4 KiB
Rust
use std::{net::SocketAddr, path::Path};
|
|
|
|
use anyhow::{Context as _, Result};
|
|
pub use indexer_core::config::*;
|
|
use indexer_service_rpc::RpcServer as _;
|
|
use jsonrpsee::server::{Server, ServerHandle};
|
|
use log::{error, info};
|
|
|
|
pub mod service;
|
|
|
|
#[cfg(feature = "mock-responses")]
|
|
pub mod mock_service;
|
|
|
|
pub struct IndexerHandle {
|
|
addr: SocketAddr,
|
|
/// Option because of `Drop` which forbids to simply move out of `self` in `stopped()`.
|
|
server_handle: Option<ServerHandle>,
|
|
}
|
|
|
|
impl IndexerHandle {
|
|
const fn new(addr: SocketAddr, server_handle: ServerHandle) -> Self {
|
|
Self {
|
|
addr,
|
|
server_handle: Some(server_handle),
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub const fn addr(&self) -> SocketAddr {
|
|
self.addr
|
|
}
|
|
|
|
/// Wait for all Indexer tasks to stop.
|
|
pub async fn stopped(mut self) {
|
|
let handle = self
|
|
.server_handle
|
|
.take()
|
|
.expect("Indexer server handle is set");
|
|
|
|
handle.stopped().await;
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn is_healthy(&self) -> bool {
|
|
self.server_handle
|
|
.as_ref()
|
|
.is_some_and(|handle| !handle.is_stopped())
|
|
}
|
|
}
|
|
|
|
impl Drop for IndexerHandle {
|
|
fn drop(&mut self) {
|
|
let Self {
|
|
addr: _,
|
|
server_handle,
|
|
} = self;
|
|
|
|
let Some(handle) = server_handle else {
|
|
return;
|
|
};
|
|
|
|
if let Err(err) = handle.stop() {
|
|
error!("An error occurred while stopping Indexer RPC server: {err}");
|
|
}
|
|
}
|
|
}
|
|
|
|
pub async fn run_server(
|
|
config: IndexerConfig,
|
|
storage_dir: &Path,
|
|
port: u16,
|
|
) -> Result<IndexerHandle> {
|
|
#[cfg(feature = "mock-responses")]
|
|
let _ = (config, storage_dir);
|
|
|
|
let server = Server::builder()
|
|
.build(SocketAddr::from(([0, 0, 0, 0], port)))
|
|
.await
|
|
.context("Failed to build RPC server")?;
|
|
|
|
let addr = server
|
|
.local_addr()
|
|
.context("Failed to get local address of RPC server")?;
|
|
|
|
info!("Starting Indexer Service RPC server on {addr}");
|
|
|
|
#[cfg(not(feature = "mock-responses"))]
|
|
let handle = {
|
|
let service = service::IndexerService::new(config, storage_dir)
|
|
.context("Failed to initialize indexer service")?;
|
|
server.start(service.into_rpc())
|
|
};
|
|
#[cfg(feature = "mock-responses")]
|
|
let handle = server.start(mock_service::MockIndexerService::new_with_mock_blocks().into_rpc());
|
|
|
|
Ok(IndexerHandle::new(addr, handle))
|
|
}
|