Skip to content

Commit bed0f7f

Browse files
author
jrconlin
committed
feat: Swtich to lighter weight health check
Closes SYNC-4197
1 parent 56658bf commit bed0f7f

2 files changed

Lines changed: 45 additions & 21 deletions

File tree

autopush-common/src/db/bigtable/bigtable_client/mod.rs

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use cadence::{CountedExt, StatsdClient};
1111
use futures_util::StreamExt;
1212
use google_cloud_rust_raw::bigtable::admin::v2::bigtable_table_admin::DropRowRangeRequest;
1313
use google_cloud_rust_raw::bigtable::admin::v2::bigtable_table_admin_grpc::BigtableTableAdminClient;
14-
use google_cloud_rust_raw::bigtable::v2::bigtable::ReadRowsRequest;
14+
use google_cloud_rust_raw::bigtable::v2::bigtable::{PingAndWarmRequest, ReadRowsRequest};
1515
use google_cloud_rust_raw::bigtable::v2::bigtable_grpc::BigtableClient;
1616
use google_cloud_rust_raw::bigtable::v2::data::{RowFilter, RowFilter_Chain};
1717
use google_cloud_rust_raw::bigtable::v2::{bigtable, data};
@@ -762,48 +762,46 @@ impl BigTableClientImpl {
762762
pub struct BigtableDb {
763763
pub(super) conn: BigtableClient,
764764
pub(super) metadata: Metadata,
765+
instance_name: String,
765766
}
766767

767768
impl BigtableDb {
768-
pub fn new(channel: Channel, metadata: &Metadata) -> Self {
769+
pub fn new(channel: Channel, metadata: &Metadata, instance_name: &str) -> Self {
769770
Self {
770771
conn: BigtableClient::new(channel),
771772
metadata: metadata.clone(),
773+
instance_name: instance_name.to_owned(),
772774
}
773775
}
774-
775776
/// Perform a simple connectivity check. This should return no actual results
776777
/// but should verify that the connection is valid. We use this for the
777778
/// Recycle check as well, so it has to be fairly low in the implementation
778779
/// stack.
779780
///
780-
pub async fn health_check(
781-
&mut self,
782-
table_name: &str,
783-
metrics: Arc<StatsdClient>,
784-
) -> DbResult<bool> {
785-
// Create a request that is GRPC valid, but does not point to a valid row.
786-
let mut req = read_row_request(table_name, "NOT FOUND");
787-
let mut filter = data::RowFilter::default();
788-
filter.set_block_all_filter(true);
789-
req.set_filter(filter);
790-
791-
let r = retry_policy(RETRY_COUNT)
781+
/// "instance_name" is the "projects/{project}/instances/{instance}" portion of
782+
/// the tablename.
783+
///
784+
pub async fn health_check(&mut self, metrics: Arc<StatsdClient>) -> DbResult<bool> {
785+
let req = PingAndWarmRequest {
786+
name: self.instance_name.clone(),
787+
..Default::default()
788+
};
789+
// PingAndWarmResponse does not implement a stream since it does not return data.
790+
let _r = retry_policy(RETRY_COUNT)
792791
.retry_if(
793792
|| async {
794793
self.conn
795-
.read_rows_opt(&req, call_opts(self.metadata.clone()))
794+
.ping_and_warm_opt(&req, call_opts(self.metadata.clone()))
796795
},
797796
retryable_error(metrics.clone()),
798797
)
799798
.await
800799
.map_err(|e| DbError::General(format!("BigTable connectivity error: {:?}", e)))?;
801800

802-
let (v, _stream) = r.into_future().await;
803801
// Since this should return no rows (with the row key set to a value that shouldn't exist)
804802
// the first component of the tuple should be None.
805803
debug!("🉑 health check");
806-
Ok(v.is_none())
804+
Ok(true)
807805
}
808806
}
809807

@@ -1321,7 +1319,7 @@ impl DbClient for BigTableClientImpl {
13211319
self.pool
13221320
.get()
13231321
.await?
1324-
.health_check(&self.settings.table_name, self.metrics.clone())
1322+
.health_check(self.metrics.clone())
13251323
.await
13261324
}
13271325

autopush-common/src/db/bigtable/pool.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,16 @@ impl BigtableClientManager {
169169
}
170170
}
171171

172+
fn get_instance_name(table_name: &str) -> Result<String, DbError> {
173+
let parts: Vec<&str> = table_name.split('/').collect();
174+
if parts.len() < 4 || parts[0] != "projects" || parts[2] != "instances" {
175+
return Err(DbError::General(
176+
"Invalid table name specified. Cannot parse instance".to_owned(),
177+
));
178+
}
179+
return Ok(parts[0..4].join("/"));
180+
}
181+
172182
impl fmt::Debug for BigtableClientManager {
173183
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
174184
fmt.debug_struct("deadpool::BtClientManager")
@@ -186,7 +196,11 @@ impl Manager for BigtableClientManager {
186196
/// `BigtableClient` is the most atomic we can go.
187197
async fn create(&self) -> Result<BigtableDb, DbError> {
188198
debug!("🏊 Create a new pool entry.");
189-
let entry = BigtableDb::new(self.get_channel()?, &self.settings.metadata()?);
199+
let entry = BigtableDb::new(
200+
self.get_channel()?,
201+
&self.settings.metadata()?,
202+
&get_instance_name(&self.settings.table_name)?,
203+
);
190204
debug!("🏊 Bigtable connection acquired");
191205
Ok(entry)
192206
}
@@ -216,7 +230,7 @@ impl Manager for BigtableClientManager {
216230
// note, this changes to `blocks_in_conditions` for 1.76+
217231
#[allow(clippy::blocks_in_conditions)]
218232
if !client
219-
.health_check(&self.settings.table_name, self.metrics.clone())
233+
.health_check(self.metrics.clone())
220234
.await
221235
.map_err(|e| {
222236
debug!("🏊 Recycle requested (health). {:?}", e);
@@ -265,3 +279,15 @@ impl BigtableClientManager {
265279
Ok(chan)
266280
}
267281
}
282+
283+
#[test]
284+
fn test_get_instance() -> Result<(), DbError> {
285+
let res = get_instance_name("projects/foo/instances/bar/tables/gorp")?;
286+
assert_eq!(res.as_str(), "projects/foo/instances/bar");
287+
288+
assert!(get_instance_name("projects/foo/").is_err());
289+
assert!(get_instance_name("protect/foo/instances/bar/tables/gorp").is_err());
290+
assert!(get_instance_name("project/foo/instance/bar/tables/gorp").is_err());
291+
292+
Ok(())
293+
}

0 commit comments

Comments
 (0)