@@ -1140,3 +1140,70 @@ func TestGossipBatching(t *testing.T) {
1140
1140
require .LessOrEqual (t , serverMessagesSentCount , upperBoundMessages )
1141
1141
require .LessOrEqual (t , clientMessagesSentCount , upperBoundMessages )
1142
1142
}
1143
+
1144
+ // TestCallbacksPendingMetricGoesToZeroOnStop verifies that the CallbacksPending
1145
+ // metric is correctly decremented when a callback is unregistered with pending work
1146
+ // or when the stopper is stopped.
1147
+ func TestCallbacksPendingMetricGoesToZeroOnStop (t * testing.T ) {
1148
+ defer leaktest .AfterTest (t )()
1149
+
1150
+ testCases := []struct {
1151
+ name string
1152
+ cleanup func (g * Gossip , unregister func (), stopper * stop.Stopper , ctx context.Context )
1153
+ }{
1154
+ {
1155
+ name : "unregister callback" ,
1156
+ cleanup : func (g * Gossip , unregister func (), stopper * stop.Stopper , ctx context.Context ) {
1157
+ unregister ()
1158
+ },
1159
+ },
1160
+ {
1161
+ name : "stopper shutdown" ,
1162
+ cleanup : func (g * Gossip , unregister func (), stopper * stop.Stopper , ctx context.Context ) {
1163
+ stopper .Stop (ctx )
1164
+ },
1165
+ },
1166
+ }
1167
+
1168
+ for _ , tc := range testCases {
1169
+ t .Run (tc .name , func (t * testing.T ) {
1170
+ ctx := context .Background ()
1171
+ stopper := stop .NewStopper ()
1172
+ defer stopper .Stop (ctx )
1173
+ g := NewTest (1 , stopper , metric .NewRegistry ())
1174
+
1175
+ unregister := g .RegisterCallback ("test.*" , func (key string , val roachpb.Value ) {
1176
+ // Do nothing.
1177
+ })
1178
+
1179
+ // Add 100 infos to the gossip that will be processed by the callback.
1180
+ for i := 0 ; i < 100 ; i ++ {
1181
+ slice := []byte ("b1" )
1182
+ require .NoError (t , g .AddInfo (fmt .Sprintf ("test.key%d" , i ), slice , time .Hour ))
1183
+ }
1184
+
1185
+ // Execute the cleanup action (either unregister or stopper.Stop)
1186
+ // We do this in a goroutine to help cause interesting potential race conditions.
1187
+ go func () {
1188
+ tc .cleanup (g , unregister , stopper , ctx )
1189
+ }()
1190
+
1191
+ // Add another 100 infos to the gossip that will be processed by the callback.
1192
+ // We do this in a goroutine to help cause interesting potential race conditions.
1193
+ go func () {
1194
+ for i := 0 ; i < 100 ; i ++ {
1195
+ slice := []byte ("b2" )
1196
+ require .NoError (t , g .AddInfo (fmt .Sprintf ("test.key%d" , i ), slice , time .Hour ))
1197
+ }
1198
+ }()
1199
+
1200
+ // Wait for the pending callbacks metric to go to 0.
1201
+ testutils .SucceedsSoon (t , func () error {
1202
+ if g .mu .is .metrics .CallbacksPending .Value () != 0 {
1203
+ return fmt .Errorf ("CallbacksPending should be 0, got %d" , g .mu .is .metrics .CallbacksPending .Value ())
1204
+ }
1205
+ return nil
1206
+ })
1207
+ })
1208
+ }
1209
+ }
0 commit comments