@@ -12,8 +12,9 @@ use crate::identity::Identity;
1212use crate :: json:: client_api:: { SubscriptionUpdateJson , TableRowOperationJson , TableUpdateJson } ;
1313use crate :: protobuf:: client_api:: { table_row_operation, SubscriptionUpdate , TableRowOperation , TableUpdate } ;
1414use crate :: subscription:: module_subscription_actor:: ModuleSubscriptionManager ;
15- use crate :: util:: lending_pool:: { Closed , LendingPool , LentResource , PoolClosed } ;
15+ use crate :: util:: lending_pool:: { Closed , LendingPool , LentResource , PoolClosed , WaiterGauge } ;
1616use crate :: util:: notify_once:: NotifyOnce ;
17+ use crate :: util:: prometheus_handle:: { GaugeInc , IntGaugeExt } ;
1718use crate :: worker_metrics:: WORKER_METRICS ;
1819use base64:: { engine:: general_purpose:: STANDARD as BASE_64_STD , Engine as _} ;
1920use futures:: { Future , FutureExt } ;
@@ -333,7 +334,10 @@ impl fmt::Debug for ModuleHost {
333334
334335#[ async_trait:: async_trait]
335336trait DynModuleHost : Send + Sync + ' static {
336- async fn get_instance ( & self ) -> Result < ( & HostThreadpool , Box < dyn ModuleInstance > ) , NoSuchModule > ;
337+ async fn get_instance (
338+ & self ,
339+ waiter_gauge_context : <InstancePoolGauge as WaiterGauge >:: Context < ' _ > ,
340+ ) -> Result < ( & HostThreadpool , Box < dyn ModuleInstance > ) , NoSuchModule > ;
337341 fn inject_logs ( & self , log_level : LogLevel , message : & str ) ;
338342 fn one_off_query (
339343 & self ,
@@ -349,7 +353,7 @@ trait DynModuleHost: Send + Sync + 'static {
349353struct HostControllerActor < T : Module > {
350354 module : Arc < T > ,
351355 threadpool : Arc < HostThreadpool > ,
352- instance_pool : LendingPool < T :: Instance > ,
356+ instance_pool : LendingPool < T :: Instance , InstancePoolGauge > ,
353357 start : NotifyOnce ,
354358}
355359
@@ -377,18 +381,38 @@ async fn select_first<A: Future, B: Future<Output = ()>>(fut_a: A, fut_b: B) ->
377381 }
378382}
379383
384+ #[ derive( Clone ) ]
385+ struct InstancePoolGauge ;
386+
387+ impl WaiterGauge for InstancePoolGauge {
388+ type Context < ' a > = & ' a ( & ' a Identity , & ' a Hash , & ' a Address , & ' a str ) ;
389+ type IncGuard = GaugeInc ;
390+ fn inc ( & self , & ( identity, module_hash, database_address, reducer_symbol) : Self :: Context < ' _ > ) -> Self :: IncGuard {
391+ WORKER_METRICS
392+ . instance_queue_length
393+ . with_label_values ( identity, module_hash, database_address, reducer_symbol)
394+ . inc_scope ( )
395+ }
396+ }
397+
380398#[ async_trait:: async_trait]
381399impl < T : Module > DynModuleHost for HostControllerActor < T > {
382- async fn get_instance ( & self ) -> Result < ( & HostThreadpool , Box < dyn ModuleInstance > ) , NoSuchModule > {
400+ async fn get_instance (
401+ & self ,
402+ waiter_gauge_context : <InstancePoolGauge as WaiterGauge >:: Context < ' _ > ,
403+ ) -> Result < ( & HostThreadpool , Box < dyn ModuleInstance > ) , NoSuchModule > {
383404 self . start . notified ( ) . await ;
384405 // in the future we should do something like in the else branch here -- add more instances based on load.
385406 // we need to do write-skew retries first - right now there's only ever once instance per module.
386407 let inst = if true {
387- self . instance_pool . request ( ) . await . map_err ( |_| NoSuchModule ) ?
408+ self . instance_pool
409+ . request_with_context ( waiter_gauge_context)
410+ . await
411+ . map_err ( |_| NoSuchModule ) ?
388412 } else {
389413 const GET_INSTANCE_TIMEOUT : Duration = Duration :: from_millis ( 500 ) ;
390414 select_first (
391- self . instance_pool . request ( ) ,
415+ self . instance_pool . request_with_context ( waiter_gauge_context ) ,
392416 tokio:: time:: sleep ( GET_INSTANCE_TIMEOUT ) . map ( |( ) | self . spinup_new_instance ( ) ) ,
393417 )
394418 . await
@@ -476,11 +500,7 @@ pub enum InitDatabaseError {
476500impl ModuleHost {
477501 pub fn new ( threadpool : Arc < HostThreadpool > , mut module : impl Module ) -> Self {
478502 let info = module. info ( ) ;
479- let waiter_gauge =
480- WORKER_METRICS
481- . instance_queue_length
482- . with_label_values ( & info. identity , & info. module_hash , & info. address ) ;
483- let instance_pool = LendingPool :: new ( waiter_gauge) ;
503+ let instance_pool = LendingPool :: with_gauge ( InstancePoolGauge ) ;
484504 instance_pool. add_multiple ( module. initial_instances ( ) ) . unwrap ( ) ;
485505 let inner = Arc :: new ( HostControllerActor {
486506 module : Arc :: new ( module) ,
@@ -505,12 +525,18 @@ impl ModuleHost {
505525 & self . info . subscription
506526 }
507527
508- async fn call < F , R > ( & self , f : F ) -> Result < R , NoSuchModule >
528+ async fn call < F , R > ( & self , reducer_name : & str , f : F ) -> Result < R , NoSuchModule >
509529 where
510530 F : FnOnce ( & mut dyn ModuleInstance ) -> R + Send + ' static ,
511531 R : Send + ' static ,
512532 {
513- let ( threadpool, mut inst) = self . inner . get_instance ( ) . await ?;
533+ let waiter_gauge_context = (
534+ & self . info . identity ,
535+ & self . info . module_hash ,
536+ & self . info . address ,
537+ reducer_name,
538+ ) ;
539+ let ( threadpool, mut inst) = self . inner . get_instance ( & waiter_gauge_context) . await ?;
514540
515541 let ( tx, rx) = oneshot:: channel ( ) ;
516542 threadpool. spawn ( move || {
@@ -561,7 +587,7 @@ impl ModuleHost {
561587 let args = args. into_tuple ( self . info . typespace . with_type ( schema) ) ?;
562588 let caller_address = caller_address. unwrap_or ( Address :: __DUMMY) ;
563589
564- self . call ( move |inst| {
590+ self . call ( reducer_name , move |inst| {
565591 inst. call_reducer ( CallReducerParams {
566592 timestamp : Timestamp :: now ( ) ,
567593 caller_identity,
@@ -619,13 +645,13 @@ impl ModuleHost {
619645 Some ( schema) => args. into_tuple ( schema) ?,
620646 _ => ArgsTuple :: default ( ) ,
621647 } ;
622- self . call ( move |inst| inst. init_database ( fence, args) )
648+ self . call ( "<init_database>" , move |inst| inst. init_database ( fence, args) )
623649 . await ?
624650 . map_err ( InitDatabaseError :: Other )
625651 }
626652
627653 pub async fn update_database ( & self , fence : u128 ) -> Result < UpdateDatabaseResult , anyhow:: Error > {
628- self . call ( move |inst| inst. update_database ( fence) )
654+ self . call ( "<update_database>" , move |inst| inst. update_database ( fence) )
629655 . await ?
630656 . map_err ( Into :: into)
631657 }
0 commit comments