@@ -158,6 +158,23 @@ class WeightedTargetLb : public LoadBalancingPolicy {
158
158
RefCountedPtr<WeightedChild> weighted_child_;
159
159
};
160
160
161
+ class DelayedRemovalTimer
162
+ : public InternallyRefCounted<DelayedRemovalTimer> {
163
+ public:
164
+ explicit DelayedRemovalTimer (RefCountedPtr<WeightedChild> weighted_child);
165
+
166
+ void Orphan () override ;
167
+
168
+ private:
169
+ static void OnTimer (void * arg, grpc_error_handle error);
170
+ void OnTimerLocked (grpc_error_handle error);
171
+
172
+ RefCountedPtr<WeightedChild> weighted_child_;
173
+ grpc_timer timer_;
174
+ grpc_closure on_timer_;
175
+ bool timer_pending_ = true ;
176
+ };
177
+
161
178
// Methods for dealing with the child policy.
162
179
OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked (
163
180
const grpc_channel_args* args);
@@ -166,9 +183,6 @@ class WeightedTargetLb : public LoadBalancingPolicy {
166
183
grpc_connectivity_state state, const absl::Status& status,
167
184
std::unique_ptr<SubchannelPicker> picker);
168
185
169
- static void OnDelayedRemovalTimer (void * arg, grpc_error_handle error);
170
- void OnDelayedRemovalTimerLocked (grpc_error_handle error);
171
-
172
186
// The owning LB policy.
173
187
RefCountedPtr<WeightedTargetLb> weighted_target_policy_;
174
188
@@ -182,11 +196,7 @@ class WeightedTargetLb : public LoadBalancingPolicy {
182
196
grpc_connectivity_state connectivity_state_ = GRPC_CHANNEL_CONNECTING;
183
197
bool seen_failure_since_ready_ = false ;
184
198
185
- // States for delayed removal.
186
- grpc_timer delayed_removal_timer_;
187
- grpc_closure on_delayed_removal_timer_;
188
- bool delayed_removal_timer_callback_pending_ = false ;
189
- bool shutdown_ = false ;
199
+ OrphanablePtr<DelayedRemovalTimer> delayed_removal_timer_;
190
200
};
191
201
192
202
~WeightedTargetLb () override ;
@@ -401,6 +411,53 @@ void WeightedTargetLb::UpdateStateLocked() {
401
411
std::move (picker));
402
412
}
403
413
414
+ //
415
+ // WeightedTargetLb::WeightedChild::DelayedRemovalTimer
416
+ //
417
+
418
+ WeightedTargetLb::WeightedChild::DelayedRemovalTimer::DelayedRemovalTimer (
419
+ RefCountedPtr<WeightedTargetLb::WeightedChild> weighted_child)
420
+ : weighted_child_(std::move(weighted_child)) {
421
+ GRPC_CLOSURE_INIT (&on_timer_, OnTimer, this , nullptr );
422
+ Ref ().release ();
423
+ grpc_timer_init (&timer_, ExecCtx::Get ()->Now () + kChildRetentionInterval ,
424
+ &on_timer_);
425
+ }
426
+
427
+ void WeightedTargetLb::WeightedChild::DelayedRemovalTimer::Orphan () {
428
+ if (timer_pending_) {
429
+ if (GRPC_TRACE_FLAG_ENABLED (grpc_lb_weighted_target_trace)) {
430
+ gpr_log (GPR_INFO,
431
+ " [weighted_target_lb %p] WeightedChild %p %s: cancelling "
432
+ " delayed removal timer" ,
433
+ weighted_child_->weighted_target_policy_ .get (),
434
+ weighted_child_.get (), weighted_child_->name_ .c_str ());
435
+ }
436
+ timer_pending_ = false ;
437
+ grpc_timer_cancel (&timer_);
438
+ }
439
+ Unref ();
440
+ }
441
+
442
+ void WeightedTargetLb::WeightedChild::DelayedRemovalTimer::OnTimer (
443
+ void * arg, grpc_error_handle error) {
444
+ auto * self = static_cast <DelayedRemovalTimer*>(arg);
445
+ (void )GRPC_ERROR_REF (error); // ref owned by lambda
446
+ self->weighted_child_ ->weighted_target_policy_ ->work_serializer ()->Run (
447
+ [self, error]() { self->OnTimerLocked (error); }, DEBUG_LOCATION);
448
+ }
449
+
450
+ void WeightedTargetLb::WeightedChild::DelayedRemovalTimer::OnTimerLocked (
451
+ grpc_error_handle error) {
452
+ if (error == GRPC_ERROR_NONE && timer_pending_) {
453
+ timer_pending_ = false ;
454
+ weighted_child_->weighted_target_policy_ ->targets_ .erase (
455
+ weighted_child_->name_ );
456
+ }
457
+ GRPC_ERROR_UNREF (error);
458
+ Unref ();
459
+ }
460
+
404
461
//
405
462
// WeightedTargetLb::WeightedChild
406
463
//
@@ -413,8 +470,6 @@ WeightedTargetLb::WeightedChild::WeightedChild(
413
470
gpr_log (GPR_INFO, " [weighted_target_lb %p] created WeightedChild %p for %s" ,
414
471
weighted_target_policy_.get (), this , name_.c_str ());
415
472
}
416
- GRPC_CLOSURE_INIT (&on_delayed_removal_timer_, OnDelayedRemovalTimer, this ,
417
- grpc_schedule_on_exec_ctx);
418
473
}
419
474
420
475
WeightedTargetLb::WeightedChild::~WeightedChild () {
@@ -441,11 +496,7 @@ void WeightedTargetLb::WeightedChild::Orphan() {
441
496
// Drop our ref to the child's picker, in case it's holding a ref to
442
497
// the child.
443
498
picker_wrapper_.reset ();
444
- if (delayed_removal_timer_callback_pending_) {
445
- delayed_removal_timer_callback_pending_ = false ;
446
- grpc_timer_cancel (&delayed_removal_timer_);
447
- }
448
- shutdown_ = true ;
499
+ delayed_removal_timer_.reset ();
449
500
Unref ();
450
501
}
451
502
@@ -484,14 +535,13 @@ void WeightedTargetLb::WeightedChild::UpdateLocked(
484
535
// Update child weight.
485
536
weight_ = config.weight ;
486
537
// Reactivate if needed.
487
- if (delayed_removal_timer_callback_pending_ ) {
538
+ if (delayed_removal_timer_ != nullptr ) {
488
539
if (GRPC_TRACE_FLAG_ENABLED (grpc_lb_weighted_target_trace)) {
489
540
gpr_log (GPR_INFO,
490
541
" [weighted_target_lb %p] WeightedChild %p %s: reactivating" ,
491
542
weighted_target_policy_.get (), this , name_.c_str ());
492
543
}
493
- delayed_removal_timer_callback_pending_ = false ;
494
- grpc_timer_cancel (&delayed_removal_timer_);
544
+ delayed_removal_timer_.reset ();
495
545
}
496
546
// Create child policy if needed.
497
547
if (child_policy_ == nullptr ) {
@@ -561,31 +611,8 @@ void WeightedTargetLb::WeightedChild::DeactivateLocked() {
561
611
// Set the child weight to 0 so that future picker won't contain this child.
562
612
weight_ = 0 ;
563
613
// Start a timer to delete the child.
564
- Ref (DEBUG_LOCATION, " WeightedChild+timer" ).release ();
565
- delayed_removal_timer_callback_pending_ = true ;
566
- grpc_timer_init (&delayed_removal_timer_,
567
- ExecCtx::Get ()->Now () + kChildRetentionInterval ,
568
- &on_delayed_removal_timer_);
569
- }
570
-
571
- void WeightedTargetLb::WeightedChild::OnDelayedRemovalTimer (
572
- void * arg, grpc_error_handle error) {
573
- WeightedChild* self = static_cast <WeightedChild*>(arg);
574
- (void )GRPC_ERROR_REF (error); // ref owned by lambda
575
- self->weighted_target_policy_ ->work_serializer ()->Run (
576
- [self, error]() { self->OnDelayedRemovalTimerLocked (error); },
577
- DEBUG_LOCATION);
578
- }
579
-
580
- void WeightedTargetLb::WeightedChild::OnDelayedRemovalTimerLocked (
581
- grpc_error_handle error) {
582
- if (error == GRPC_ERROR_NONE && delayed_removal_timer_callback_pending_ &&
583
- !shutdown_ && weight_ == 0 ) {
584
- delayed_removal_timer_callback_pending_ = false ;
585
- weighted_target_policy_->targets_ .erase (name_);
586
- }
587
- Unref (DEBUG_LOCATION, " WeightedChild+timer" );
588
- GRPC_ERROR_UNREF (error);
614
+ delayed_removal_timer_ = MakeOrphanable<DelayedRemovalTimer>(
615
+ Ref (DEBUG_LOCATION, " DelayedRemovalTimer" ));
589
616
}
590
617
591
618
//
0 commit comments