micromegas_ingestion/
remote_data_lake.rs1use crate::data_lake_connection::DataLakeConnection;
2use crate::data_lake_connection::make_cache;
3use crate::sql_migration::LATEST_DATA_LAKE_SCHEMA_VERSION;
4use crate::sql_migration::execute_migration;
5use crate::sql_migration::read_data_lake_schema_version;
6use anyhow::{Context, Result};
7use micromegas_object_cache::prefetch::{ObjectPrefetch, PrefixPrefetch};
8use micromegas_telemetry::blob_storage::BlobStorage;
9use micromegas_tracing::prelude::*;
10use std::sync::Arc;
11
12pub async fn acquire_lock(tr: &mut sqlx::Transaction<'_, sqlx::Postgres>, key: i64) -> Result<()> {
14 sqlx::query("SELECT pg_advisory_xact_lock($1)")
15 .bind(key)
16 .execute(&mut **tr)
17 .await?;
18 Ok(())
19}
20
21pub async fn migrate_db(pool: sqlx::Pool<sqlx::Postgres>) -> Result<()> {
23 let mut tr = pool.begin().await?;
24 let mut current_version = read_data_lake_schema_version(&mut tr).await;
25 drop(tr);
26 info!("current data lake schema: {}", current_version);
27 if current_version != LATEST_DATA_LAKE_SCHEMA_VERSION {
28 let mut tr = pool.begin().await?;
29 acquire_lock(&mut tr, 0).await?;
30 current_version = read_data_lake_schema_version(&mut pool.begin().await?).await;
31 if LATEST_DATA_LAKE_SCHEMA_VERSION == current_version {
32 return Ok(());
33 }
34 if let Err(e) = execute_migration(pool.clone()).await {
35 error!("Error migrating database: {}", e);
36 return Err(e);
37 }
38 current_version = read_data_lake_schema_version(&mut tr).await;
39 }
40 assert_eq!(current_version, LATEST_DATA_LAKE_SCHEMA_VERSION);
41 Ok(())
42}
43
44pub async fn connect_to_remote_data_lake(
46 db_uri: &str,
47 object_store_url: &str,
48) -> Result<DataLakeConnection> {
49 info!("connecting to blob storage");
50 let (raw_store, root) = BlobStorage::parse_url_opts(object_store_url)
51 .with_context(|| "connecting to blob storage")?;
52 let (layered, prefetch_client) = make_cache(raw_store);
53 let blob_storage = Arc::new(BlobStorage::new(layered, root.clone()));
54 let prefetch =
55 prefetch_client.map(|p| Arc::new(PrefixPrefetch::new(p, root)) as Arc<dyn ObjectPrefetch>);
56 let pool = sqlx::postgres::PgPoolOptions::new()
57 .connect(db_uri)
58 .await
59 .with_context(|| String::from("Connecting to telemetry database"))?;
60 migrate_db(pool.clone()).await?;
61 Ok(DataLakeConnection::new_with_prefetch(
62 pool,
63 blob_storage,
64 prefetch,
65 ))
66}