Skip to content

Commit 626c9be

Browse files
committed
Move the pool acquisition metric logic to the PgRepositoryFactory
1 parent 03bad37 commit 626c9be

File tree

8 files changed

+53
-27
lines changed

8 files changed

+53
-27
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/cli/src/app_state.rs

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// SPDX-License-Identifier: AGPL-3.0-only
55
// Please see LICENSE in the repository root for full details.
66

7-
use std::{convert::Infallible, net::IpAddr, sync::Arc, time::Instant};
7+
use std::{convert::Infallible, net::IpAddr, sync::Arc};
88

99
use axum::extract::{FromRef, FromRequestParts};
1010
use ipnetwork::IpNetwork;
@@ -19,10 +19,12 @@ use mas_keystore::{Encrypter, Keystore};
1919
use mas_matrix::HomeserverConnection;
2020
use mas_policy::{Policy, PolicyFactory};
2121
use mas_router::UrlBuilder;
22-
use mas_storage::{BoxClock, BoxRepository, BoxRepositoryFactory, BoxRng, SystemClock, RepositoryFactory};
22+
use mas_storage::{
23+
BoxClock, BoxRepository, BoxRepositoryFactory, BoxRng, RepositoryFactory, SystemClock,
24+
};
2325
use mas_storage_pg::PgRepositoryFactory;
2426
use mas_templates::Templates;
25-
use opentelemetry::{KeyValue, metrics::Histogram};
27+
use opentelemetry::KeyValue;
2628
use rand::SeedableRng;
2729
use sqlx::PgPool;
2830
use tracing::Instrument;
@@ -47,7 +49,6 @@ pub struct AppState {
4749
pub activity_tracker: ActivityTracker,
4850
pub trusted_proxies: Vec<IpNetwork>,
4951
pub limiter: Limiter,
50-
pub conn_acquisition_histogram: Option<Histogram<u64>>,
5152
}
5253

5354
impl AppState {
@@ -76,14 +77,6 @@ impl AppState {
7677
instrument.observe(i64::from(max_conn), &[]);
7778
})
7879
.build();
79-
80-
// Track the connection acquisition time
81-
let histogram = METER
82-
.u64_histogram("db.client.connections.create_time")
83-
.with_description("The time it took to create a new connection.")
84-
.with_unit("ms")
85-
.build();
86-
self.conn_acquisition_histogram = Some(histogram);
8780
}
8881

8982
/// Init the metadata cache in the background
@@ -371,17 +364,7 @@ impl FromRequestParts<AppState> for BoxRepository {
371364
_parts: &mut axum::http::request::Parts,
372365
state: &AppState,
373366
) -> Result<Self, Self::Rejection> {
374-
let start = Instant::now();
375367
let repo = state.repository_factory.create().await?;
376-
377-
// Measure the time it took to create the connection
378-
let duration = start.elapsed();
379-
let duration_ms = duration.as_millis().try_into().unwrap_or(u64::MAX);
380-
381-
if let Some(histogram) = &state.conn_acquisition_histogram {
382-
histogram.record(duration_ms, &[]);
383-
}
384-
385368
Ok(repo)
386369
}
387370
}

crates/cli/src/commands/server.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use mas_handlers::{ActivityTracker, CookieManager, Limiter, MetadataCache};
1818
use mas_listener::server::Server;
1919
use mas_router::UrlBuilder;
2020
use mas_storage::SystemClock;
21-
use mas_storage_pg::{PgRepositoryFactory, MIGRATOR};
21+
use mas_storage_pg::{MIGRATOR, PgRepositoryFactory};
2222
use sqlx::migrate::Migrate;
2323
use tracing::{Instrument, info, info_span, warn};
2424

@@ -242,7 +242,6 @@ impl Options {
242242
activity_tracker,
243243
trusted_proxies,
244244
limiter,
245-
conn_acquisition_histogram: None,
246245
};
247246
s.init_metrics();
248247
s.init_metadata_cache();

crates/storage-pg/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ serde_json.workspace = true
2121
thiserror.workspace = true
2222
tracing.workspace = true
2323
futures-util.workspace = true
24+
opentelemetry.workspace = true
2425
opentelemetry-semantic-conventions.workspace = true
2526

2627
rand.workspace = true

crates/storage-pg/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ pub(crate) mod iden;
175175
pub(crate) mod pagination;
176176
pub(crate) mod policy_data;
177177
pub(crate) mod repository;
178+
pub(crate) mod telemetry;
178179
pub(crate) mod tracing;
179180

180181
pub(crate) use self::errors::DatabaseInconsistencyError;

crates/storage-pg/src/repository.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ use crate::{
4848
job::PgQueueJobRepository, schedule::PgQueueScheduleRepository,
4949
worker::PgQueueWorkerRepository,
5050
},
51+
telemetry::DB_CLIENT_CONNECTIONS_CREATE_TIME_HISTOGRAM,
5152
upstream_oauth2::{
5253
PgUpstreamOAuthLinkRepository, PgUpstreamOAuthProviderRepository,
5354
PgUpstreamOAuthSessionRepository,
@@ -89,10 +90,18 @@ impl PgRepositoryFactory {
8990
#[async_trait]
9091
impl RepositoryFactory for PgRepositoryFactory {
9192
async fn create(&self) -> Result<BoxRepository, RepositoryError> {
92-
Ok(PgRepository::from_pool(&self.pool)
93+
let start = std::time::Instant::now();
94+
let repo = PgRepository::from_pool(&self.pool)
9395
.await
9496
.map_err(RepositoryError::from_error)?
95-
.boxed())
97+
.boxed();
98+
99+
// Measure the time it took to create the connection
100+
let duration = start.elapsed();
101+
let duration_ms = duration.as_millis().try_into().unwrap_or(u64::MAX);
102+
DB_CLIENT_CONNECTIONS_CREATE_TIME_HISTOGRAM.record(duration_ms, &[]);
103+
104+
Ok(repo)
96105
}
97106
}
98107

crates/storage-pg/src/telemetry.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2025 New Vector Ltd.
2+
//
3+
// SPDX-License-Identifier: AGPL-3.0-only
4+
// Please see LICENSE in the repository root for full details.
5+
6+
use std::sync::LazyLock;
7+
8+
use opentelemetry::{
9+
InstrumentationScope,
10+
metrics::{Histogram, Meter},
11+
};
12+
use opentelemetry_semantic_conventions as semcov;
13+
14+
static SCOPE: LazyLock<InstrumentationScope> = LazyLock::new(|| {
15+
InstrumentationScope::builder(env!("CARGO_PKG_NAME"))
16+
.with_version(env!("CARGO_PKG_VERSION"))
17+
.with_schema_url(semcov::SCHEMA_URL)
18+
.build()
19+
});
20+
21+
static METER: LazyLock<Meter> =
22+
LazyLock::new(|| opentelemetry::global::meter_with_scope(SCOPE.clone()));
23+
24+
pub(crate) static DB_CLIENT_CONNECTIONS_CREATE_TIME_HISTOGRAM: LazyLock<Histogram<u64>> =
25+
LazyLock::new(|| {
26+
METER
27+
.u64_histogram("db.client.connections.create_time")
28+
.with_description("The time it took to create a new connection.")
29+
.with_unit("ms")
30+
.build()
31+
});

crates/storage/src/repository.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ use crate::{
3131
};
3232

3333
/// A [`RepositoryFactory`] is a factory that can create a [`BoxRepository`]
34-
// XXX(quenting): this could be generic over the repository type, but it's annoying to make it dyn-safe
34+
// XXX(quenting): this could be generic over the repository type, but it's annoying to make it
35+
// dyn-safe
3536
#[async_trait]
3637
pub trait RepositoryFactory {
3738
/// Create a new [`BoxRepository`]

0 commit comments

Comments
 (0)