mirror of
https://github.com/scsibug/nostr-rs-relay.git
synced 2024-11-22 09:09:07 -05:00
feat: allow database directory configuration
Adds configuration options for database directory, either on command line through (--db dir-name) or the config.toml file. Fixes: https://todo.sr.ht/~gheartsfield/nostr-rs-relay/13
This commit is contained in:
parent
f7f12a7984
commit
5a19a8876f
|
@ -35,9 +35,7 @@ COPY --from=builder /nostr-rs-relay/target/release/nostr-rs-relay ${APP}/nostr-r
|
||||||
RUN chown -R $APP_USER:$APP_USER ${APP}
|
RUN chown -R $APP_USER:$APP_USER ${APP}
|
||||||
|
|
||||||
USER $APP_USER
|
USER $APP_USER
|
||||||
WORKDIR ${APP_DATA}
|
WORKDIR ${APP}
|
||||||
|
|
||||||
ENV RUST_LOG=info
|
ENV RUST_LOG=info
|
||||||
|
CMD ["./nostr-rs-relay --db $APP_DATA"]
|
||||||
|
|
||||||
CMD ["../nostr-rs-relay"]
|
|
||||||
|
|
12
config.toml
12
config.toml
|
@ -1,4 +1,8 @@
|
||||||
# Nostr-rs-relay configuration
|
# Nostr-rs-relay configuration
|
||||||
|
[database]
|
||||||
|
# Directory for SQLite files. Defaults to the current directory. Can
|
||||||
|
# also be specified with the "--db dirname" command line option.
|
||||||
|
data_directory = "data"
|
||||||
|
|
||||||
[network]
|
[network]
|
||||||
# Bind to this network address
|
# Bind to this network address
|
||||||
|
@ -18,15 +22,15 @@ port = 8080
|
||||||
messages_per_sec = 0
|
messages_per_sec = 0
|
||||||
|
|
||||||
# Maximum WebSocket message in bytes. Defaults to 128k.
|
# Maximum WebSocket message in bytes. Defaults to 128k.
|
||||||
#max_ws_message_bytes = 131072
|
max_ws_message_bytes = 131072
|
||||||
|
|
||||||
# Maximum WebSocket frame size in bytes. Defaults to 128k.
|
# Maximum WebSocket frame size in bytes. Defaults to 128k.
|
||||||
#max_ws_frame_bytes = 131072
|
max_ws_frame_bytes = 131072
|
||||||
|
|
||||||
# Broadcast buffer size, in number of events. This prevents slow
|
# Broadcast buffer size, in number of events. This prevents slow
|
||||||
# readers from consuming memory. Defaults to 4096.
|
# readers from consuming memory. Defaults to 4096.
|
||||||
#broadcast_buffer = 4096
|
broadcast_buffer = 4096
|
||||||
|
|
||||||
# Event persistence buffer size, in number of events. This provides
|
# Event persistence buffer size, in number of events. This provides
|
||||||
# backpressure to senders if writes are slow. Defaults to 16.
|
# backpressure to senders if writes are slow. Defaults to 16.
|
||||||
#event_persist_buffer = 16
|
event_persist_buffer = 16
|
||||||
|
|
|
@ -8,6 +8,12 @@ lazy_static! {
|
||||||
pub static ref SETTINGS: RwLock<Settings> = RwLock::new(Settings::default());
|
pub static ref SETTINGS: RwLock<Settings> = RwLock::new(Settings::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[allow(unused)]
|
||||||
|
pub struct Database {
|
||||||
|
pub data_directory: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub struct Network {
|
pub struct Network {
|
||||||
|
@ -46,6 +52,7 @@ pub struct Limits {
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
|
pub database: Database,
|
||||||
pub network: Network,
|
pub network: Network,
|
||||||
pub limits: Limits,
|
pub limits: Limits,
|
||||||
pub retention: Retention,
|
pub retention: Retention,
|
||||||
|
@ -82,6 +89,9 @@ impl Settings {
|
||||||
impl Default for Settings {
|
impl Default for Settings {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Settings {
|
Settings {
|
||||||
|
database: Database {
|
||||||
|
data_directory: ".".to_owned(),
|
||||||
|
},
|
||||||
network: Network {
|
network: Network {
|
||||||
port: 8080,
|
port: 8080,
|
||||||
address: "0.0.0.0".to_owned(),
|
address: "0.0.0.0".to_owned(),
|
||||||
|
|
17
src/db.rs
17
src/db.rs
|
@ -122,14 +122,18 @@ pub async fn db_writer(
|
||||||
mut shutdown: tokio::sync::broadcast::Receiver<()>,
|
mut shutdown: tokio::sync::broadcast::Receiver<()>,
|
||||||
) -> tokio::task::JoinHandle<Result<()>> {
|
) -> tokio::task::JoinHandle<Result<()>> {
|
||||||
task::spawn_blocking(move || {
|
task::spawn_blocking(move || {
|
||||||
|
// get database configuration settings
|
||||||
|
let config = SETTINGS.read().unwrap();
|
||||||
|
let db_dir = &config.database.data_directory;
|
||||||
|
let full_path = Path::new(db_dir).join(DB_FILE);
|
||||||
|
// create a connection
|
||||||
let mut conn = Connection::open_with_flags(
|
let mut conn = Connection::open_with_flags(
|
||||||
Path::new(DB_FILE),
|
&full_path,
|
||||||
OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_CREATE,
|
OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_CREATE,
|
||||||
)?;
|
)?;
|
||||||
info!("opened database for writing");
|
info!("opened database {:?} for writing", full_path);
|
||||||
upgrade_db(&mut conn)?;
|
upgrade_db(&mut conn)?;
|
||||||
// get rate limit settings
|
// get rate limit settings
|
||||||
let config = SETTINGS.read().unwrap();
|
|
||||||
let rps_setting = config.limits.messages_per_sec;
|
let rps_setting = config.limits.messages_per_sec;
|
||||||
let mut lim_opt = None;
|
let mut lim_opt = None;
|
||||||
let clock = governor::clock::QuantaClock::default();
|
let clock = governor::clock::QuantaClock::default();
|
||||||
|
@ -373,9 +377,12 @@ pub async fn db_query(
|
||||||
mut abandon_query_rx: tokio::sync::oneshot::Receiver<()>,
|
mut abandon_query_rx: tokio::sync::oneshot::Receiver<()>,
|
||||||
) {
|
) {
|
||||||
task::spawn_blocking(move || {
|
task::spawn_blocking(move || {
|
||||||
|
let config = SETTINGS.read().unwrap();
|
||||||
|
let db_dir = &config.database.data_directory;
|
||||||
|
let full_path = Path::new(db_dir).join(DB_FILE);
|
||||||
|
|
||||||
let conn =
|
let conn =
|
||||||
Connection::open_with_flags(Path::new(DB_FILE), OpenFlags::SQLITE_OPEN_READ_ONLY)
|
Connection::open_with_flags(&full_path, OpenFlags::SQLITE_OPEN_READ_ONLY).unwrap();
|
||||||
.unwrap();
|
|
||||||
debug!("opened database for reading");
|
debug!("opened database for reading");
|
||||||
debug!("going to query for: {:?}", sub);
|
debug!("going to query for: {:?}", sub);
|
||||||
// generate SQL query
|
// generate SQL query
|
||||||
|
|
|
@ -36,6 +36,8 @@ pub enum Error {
|
||||||
SqlError(rusqlite::Error),
|
SqlError(rusqlite::Error),
|
||||||
#[error("Config error")]
|
#[error("Config error")]
|
||||||
ConfigError(config::ConfigError),
|
ConfigError(config::ConfigError),
|
||||||
|
#[error("Data directory does not exist")]
|
||||||
|
DatabaseDirError,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<rusqlite::Error> for Error {
|
impl From<rusqlite::Error> for Error {
|
||||||
|
|
26
src/main.rs
26
src/main.rs
|
@ -12,6 +12,8 @@ use nostr_rs_relay::protostream;
|
||||||
use nostr_rs_relay::protostream::NostrMessage::*;
|
use nostr_rs_relay::protostream::NostrMessage::*;
|
||||||
use nostr_rs_relay::protostream::NostrResponse::*;
|
use nostr_rs_relay::protostream::NostrResponse::*;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::env;
|
||||||
|
use std::path::Path;
|
||||||
use tokio::net::{TcpListener, TcpStream};
|
use tokio::net::{TcpListener, TcpStream};
|
||||||
use tokio::runtime::Builder;
|
use tokio::runtime::Builder;
|
||||||
use tokio::sync::broadcast;
|
use tokio::sync::broadcast;
|
||||||
|
@ -20,17 +22,39 @@ use tokio::sync::mpsc;
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
use tungstenite::protocol::WebSocketConfig;
|
use tungstenite::protocol::WebSocketConfig;
|
||||||
|
|
||||||
|
fn db_from_args(args: Vec<String>) -> Option<String> {
|
||||||
|
if args.len() == 3 {
|
||||||
|
if args.get(1) == Some(&"--db".to_owned()) {
|
||||||
|
return args.get(2).map(|x| x.to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
/// Start running a Nostr relay server.
|
/// Start running a Nostr relay server.
|
||||||
fn main() -> Result<(), Error> {
|
fn main() -> Result<(), Error> {
|
||||||
// setup logger
|
// setup logger
|
||||||
let _ = env_logger::try_init();
|
let _ = env_logger::try_init();
|
||||||
|
// get database directory from args
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
let db_dir: Option<String> = db_from_args(args);
|
||||||
|
info!("Using database: {:?}", db_dir);
|
||||||
{
|
{
|
||||||
let mut settings = config::SETTINGS.write().unwrap();
|
let mut settings = config::SETTINGS.write().unwrap();
|
||||||
// replace default settings with those read from config.toml
|
// replace default settings with those read from config.toml
|
||||||
let c = config::Settings::new();
|
let mut c = config::Settings::new();
|
||||||
|
// update with database location
|
||||||
|
if let Some(db) = db_dir {
|
||||||
|
c.database.data_directory = db.to_owned();
|
||||||
|
}
|
||||||
*settings = c;
|
*settings = c;
|
||||||
}
|
}
|
||||||
let config = config::SETTINGS.read().unwrap();
|
let config = config::SETTINGS.read().unwrap();
|
||||||
|
// do some config validation.
|
||||||
|
if !Path::new(&config.database.data_directory).is_dir() {
|
||||||
|
error!("Database directory does not exist");
|
||||||
|
return Err(Error::DatabaseDirError);
|
||||||
|
}
|
||||||
debug!("config: {:?}", config);
|
debug!("config: {:?}", config);
|
||||||
let addr = format!("{}:{}", config.network.address.trim(), config.network.port);
|
let addr = format!("{}:{}", config.network.address.trim(), config.network.port);
|
||||||
// configure tokio runtime
|
// configure tokio runtime
|
||||||
|
|
Loading…
Reference in New Issue
Block a user