@@ -752,6 +752,7 @@ impl CallProcedureParams {
752752struct ModuleInstanceManager < M : GenericModule > {
753753 instances : Mutex < VecDeque < M :: Instance > > ,
754754 module : M ,
755+ module_instances_metric : ModuleInstancesMetric ,
755756 create_instance_time_metric : CreateInstanceTimeMetric ,
756757}
757758
@@ -763,6 +764,15 @@ struct CreateInstanceTimeMetric {
763764 database_identity : Identity ,
764765}
765766
767+ /// Handle on the `spacetime_module_instances` label for a particular database
768+ /// which calls `remove_label_values` to clean up on drop.
769+ struct ModuleInstancesMetric {
770+ metric : IntGauge ,
771+ host_type : HostType ,
772+ database_identity : Identity ,
773+ count : std:: sync:: Mutex < i64 > ,
774+ }
775+
766776impl Drop for CreateInstanceTimeMetric {
767777 fn drop ( & mut self ) {
768778 let _ = WORKER_METRICS
@@ -771,6 +781,31 @@ impl Drop for CreateInstanceTimeMetric {
771781 }
772782}
773783
784+ impl Drop for ModuleInstancesMetric {
785+ fn drop ( & mut self ) {
786+ let _ = WORKER_METRICS
787+ . module_instances
788+ . remove_label_values ( & self . database_identity , & self . host_type ) ;
789+ }
790+ }
791+
792+ impl ModuleInstancesMetric {
793+ fn inc ( & self ) {
794+ let mut count = self . count . lock ( ) . unwrap ( ) ;
795+ * count += 1 ;
796+ self . metric . set ( * count) ;
797+ }
798+
799+ fn dec ( & self ) {
800+ let mut count = self . count . lock ( ) . unwrap ( ) ;
801+ if * count == 0 {
802+ return ;
803+ }
804+ * count -= 1 ;
805+ self . metric . set ( * count) ;
806+ }
807+ }
808+
774809impl CreateInstanceTimeMetric {
775810 fn observe ( & self , duration : std:: time:: Duration ) {
776811 self . metric . observe ( duration. as_secs_f64 ( ) ) ;
@@ -780,6 +815,15 @@ impl CreateInstanceTimeMetric {
780815impl < M : GenericModule > ModuleInstanceManager < M > {
781816 fn new ( module : M , init_inst : M :: Instance , database_identity : Identity ) -> Self {
782817 let host_type = module. host_type ( ) ;
818+ let module_instances_metric = ModuleInstancesMetric {
819+ metric : WORKER_METRICS
820+ . module_instances
821+ . with_label_values ( & database_identity, & host_type) ,
822+ host_type,
823+ database_identity,
824+ count : std:: sync:: Mutex :: new ( 1 ) ,
825+ } ;
826+
783827 let create_instance_time_metric = CreateInstanceTimeMetric {
784828 metric : WORKER_METRICS
785829 . module_create_instance_time_seconds
@@ -795,6 +839,7 @@ impl<M: GenericModule> ModuleInstanceManager<M> {
795839 Self {
796840 instances : Mutex :: new ( instances) ,
797841 module,
842+ module_instances_metric,
798843 create_instance_time_metric,
799844 }
800845 }
@@ -815,6 +860,7 @@ impl<M: GenericModule> ModuleInstanceManager<M> {
815860 let res = self . module . create_instance ( ) . await ;
816861 let elapsed_time = start_time. elapsed ( ) ;
817862 self . create_instance_time_metric . observe ( elapsed_time) ;
863+ self . module_instances_metric . inc ( ) ;
818864 res
819865 }
820866 }
@@ -824,6 +870,7 @@ impl<M: GenericModule> ModuleInstanceManager<M> {
824870 // Don't return trapped instances;
825871 // they may have left internal data structures in the guest `Instance`
826872 // (WASM linear memory, V8 global scope) in a bad state.
873+ self . module_instances_metric . dec ( ) ;
827874 return ;
828875 }
829876
0 commit comments