mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-16 15:21:24 +01:00
make load_or_create *only* load_or_create
Extracted the other logic to its current singular callsite for now. The load_or_create function finally does nothing other than load or create the database (and do some related checks, which is fine). This paves the way for more/better database surgery tooling.
This commit is contained in:
parent
e9caf228b3
commit
c2c6083277
3 changed files with 56 additions and 52 deletions
|
|
@ -40,11 +40,14 @@ use crate::{
|
|||
ruma_wrapper::{Ar, Ra},
|
||||
server_server, well_known,
|
||||
},
|
||||
config,
|
||||
config::{Config, ListenComponent, ListenTransport},
|
||||
config::{self, Config, ListenComponent, ListenTransport},
|
||||
database::KeyValueDatabase,
|
||||
error, observability, services, utils,
|
||||
utils::error::{Error, Result},
|
||||
error, observability, services,
|
||||
utils::{
|
||||
self,
|
||||
error::{Error, Result},
|
||||
},
|
||||
Services, SERVICES,
|
||||
};
|
||||
|
||||
pub(crate) async fn run(args: ServeArgs) -> Result<(), error::ServeCommand> {
|
||||
|
|
@ -70,8 +73,27 @@ pub(crate) async fn run(args: ServeArgs) -> Result<(), error::ServeCommand> {
|
|||
.expect("should be able to increase the soft limit to the hard limit");
|
||||
|
||||
info!("Loading database");
|
||||
let db = KeyValueDatabase::load_or_create(config, reload_handles)
|
||||
.map_err(Error::DatabaseError)?;
|
||||
let db = Box::leak(Box::new(
|
||||
KeyValueDatabase::load_or_create(&config)
|
||||
.map_err(Error::DatabaseError)?,
|
||||
));
|
||||
|
||||
// This is the first and only time we initialize the SERVICE static
|
||||
*SERVICES.write().unwrap() = Some(Box::leak(Box::new(
|
||||
Services::build(db, config, reload_handles)
|
||||
.map_err(Error::InitializeServices)?,
|
||||
)));
|
||||
|
||||
// Matrix resource ownership is based on the server name; changing it
|
||||
// requires recreating the database from scratch. This check needs to be
|
||||
// done before background tasks are started to avoid data races.
|
||||
if services().users.count().map(|x| x > 0).map_err(Error::NonZeroUsers)? {
|
||||
let admin_bot = services().globals.admin_bot_user_id.as_ref();
|
||||
if !services().users.exists(admin_bot).map_err(Error::AdminBotExists)? {
|
||||
return Err(Error::Renamed);
|
||||
}
|
||||
}
|
||||
|
||||
db.apply_migrations().await.map_err(Error::DatabaseError)?;
|
||||
|
||||
info!("Starting background tasks");
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ use tracing::{debug, error, info, info_span, warn, Instrument};
|
|||
|
||||
use crate::{
|
||||
config::DatabaseBackend,
|
||||
observability::FilterReloadHandles,
|
||||
service::{
|
||||
media::MediaFileKey,
|
||||
rooms::{
|
||||
|
|
@ -33,7 +32,7 @@ use crate::{
|
|||
timeline::PduCount,
|
||||
},
|
||||
},
|
||||
services, utils, Config, Error, PduEvent, Result, Services, SERVICES,
|
||||
services, utils, Config, Error, PduEvent, Result,
|
||||
};
|
||||
|
||||
pub(crate) struct KeyValueDatabase {
|
||||
|
|
@ -319,11 +318,8 @@ impl KeyValueDatabase {
|
|||
allow(unreachable_code)
|
||||
)]
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub(crate) fn load_or_create(
|
||||
config: Config,
|
||||
reload_handles: FilterReloadHandles,
|
||||
) -> Result<&'static KeyValueDatabase> {
|
||||
Self::check_db_setup(&config)?;
|
||||
pub(crate) fn load_or_create(config: &Config) -> Result<KeyValueDatabase> {
|
||||
Self::check_db_setup(config)?;
|
||||
|
||||
if !Path::new(&config.database.path).exists() {
|
||||
fs::create_dir_all(&config.database.path).map_err(|_| {
|
||||
|
|
@ -339,21 +335,19 @@ impl KeyValueDatabase {
|
|||
not(any(feature = "rocksdb", feature = "sqlite")),
|
||||
allow(unused_variables)
|
||||
)]
|
||||
let builder: Arc<dyn KeyValueDatabaseEngine> = match config
|
||||
.database
|
||||
.backend
|
||||
{
|
||||
#[cfg(feature = "sqlite")]
|
||||
DatabaseBackend::Sqlite => {
|
||||
Arc::new(Arc::<abstraction::sqlite::Engine>::open(&config)?)
|
||||
}
|
||||
#[cfg(feature = "rocksdb")]
|
||||
DatabaseBackend::Rocksdb => {
|
||||
Arc::new(Arc::<abstraction::rocksdb::Engine>::open(&config)?)
|
||||
}
|
||||
};
|
||||
let builder: Arc<dyn KeyValueDatabaseEngine> =
|
||||
match config.database.backend {
|
||||
#[cfg(feature = "sqlite")]
|
||||
DatabaseBackend::Sqlite => {
|
||||
Arc::new(Arc::<abstraction::sqlite::Engine>::open(config)?)
|
||||
}
|
||||
#[cfg(feature = "rocksdb")]
|
||||
DatabaseBackend::Rocksdb => {
|
||||
Arc::new(Arc::<abstraction::rocksdb::Engine>::open(config)?)
|
||||
}
|
||||
};
|
||||
|
||||
let db_raw = Box::new(Self {
|
||||
let db = Self {
|
||||
db: builder.clone(),
|
||||
userid_password: builder.open_tree("userid_password")?,
|
||||
userid_displayname: builder.open_tree("userid_displayname")?,
|
||||
|
|
@ -527,31 +521,7 @@ impl KeyValueDatabase {
|
|||
our_real_users_cache: RwLock::new(HashMap::new()),
|
||||
appservice_in_room_cache: RwLock::new(HashMap::new()),
|
||||
lasttimelinecount_cache: Mutex::new(HashMap::new()),
|
||||
});
|
||||
|
||||
let db = Box::leak(db_raw);
|
||||
|
||||
let services_raw =
|
||||
Box::new(Services::build(db, config, reload_handles)?);
|
||||
|
||||
// This is the first and only time we initialize the SERVICE static
|
||||
*SERVICES.write().unwrap() = Some(Box::leak(services_raw));
|
||||
|
||||
// Matrix resource ownership is based on the server name; changing it
|
||||
// requires recreating the database from scratch.
|
||||
if services().users.count()? > 0 {
|
||||
let admin_bot = services().globals.admin_bot_user_id.as_ref();
|
||||
if !services().users.exists(admin_bot)? {
|
||||
error!(
|
||||
user_id = %admin_bot,
|
||||
"The admin bot does not exist and the database is not new",
|
||||
);
|
||||
return Err(Error::bad_database(
|
||||
"Cannot reuse an existing database after changing the \
|
||||
server name, please delete the old one first.",
|
||||
));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(db)
|
||||
}
|
||||
|
|
|
|||
12
src/error.rs
12
src/error.rs
|
|
@ -61,6 +61,18 @@ pub(crate) enum ServeCommand {
|
|||
|
||||
#[error("failed to serve requests")]
|
||||
Serve(#[from] Serve),
|
||||
|
||||
#[error("failed to initialize services")]
|
||||
InitializeServices(#[source] crate::utils::error::Error),
|
||||
|
||||
#[error("failed to check if there are any users")]
|
||||
NonZeroUsers(#[source] crate::utils::error::Error),
|
||||
|
||||
#[error("failed to check if the admin bot exists")]
|
||||
AdminBotExists(#[source] crate::utils::error::Error),
|
||||
|
||||
#[error("`server_name` in the database and config file differ")]
|
||||
Renamed,
|
||||
}
|
||||
|
||||
/// Observability initialization errors
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue