@@ -271,7 +271,7 @@ void Constituent::candidate() {
271
271
272
272
if (_leaderID != NO_LEADER) {
273
273
_leaderID = NO_LEADER;
274
- LOG_TOPIC (DEBUG, Logger::AGENCY) << " Set _leaderID to NO_LEADER" ;
274
+ LOG_TOPIC (DEBUG, Logger::AGENCY) << " Set _leaderID to NO_LEADER in Constituent::candidate " ;
275
275
}
276
276
277
277
if (_role != CANDIDATE) {
@@ -739,35 +739,49 @@ void Constituent::run() {
739
739
} else if (role == CANDIDATE) {
740
740
callElection (); // Run for office
741
741
} else {
742
- // This is 1/4th of the minPing timeout (_cv.wait() below is in
743
- // microseconds):
744
- uint64_t timeout =
745
- static_cast <uint64_t >(250000.0 * _agent->config ().minPing () *
746
- _agent->config ().timeoutMult ());
747
- {
748
- CONDITION_LOCKER (guardv, _cv);
749
- _cv.wait (timeout);
750
- }
742
+ double interval = 0.25 * _agent->config ().minPing ()
743
+ * _agent->config ().timeoutMult ();
751
744
752
745
double now = TRI_microtime ();
746
+ double nextWakeup = interval; // might be lowered below
747
+
753
748
std::string const myid = _agent->id ();
754
749
for (auto const & followerId : _agent->config ().active ()) {
755
750
if (followerId != myid) {
756
751
bool needed = false ;
757
752
{
758
753
MUTEX_LOCKER (guard, _heartBeatMutex);
759
754
auto it = _lastHeartbeatSent.find (followerId);
760
- if (it == _lastHeartbeatSent.end () ||
761
- now - it->second > _agent->config ().minPing ()
762
- * _agent->config ().timeoutMult () / 4.0 ) {
755
+ if (it == _lastHeartbeatSent.end ()) {
763
756
needed = true ;
757
+ } else {
758
+ double diff = now - it->second ;
759
+ if (diff >= interval) {
760
+ needed = true ;
761
+ } else {
762
+ // diff < interval, so only needed again in interval-diff s
763
+ double waitOnly = interval - diff;
764
+ if (nextWakeup > waitOnly) {
765
+ nextWakeup = waitOnly;
766
+ }
767
+ LOG_TOPIC (DEBUG, Logger::AGENCY)
768
+ << " No need for empty AppendEntriesRPC: " << diff;
769
+ }
764
770
}
765
771
}
766
772
if (needed) {
767
773
_agent->sendEmptyAppendEntriesRPC (followerId);
768
774
}
769
775
}
770
776
}
777
+
778
+ // This is the smallest time until any of the followers need a
779
+ // new empty heartbeat:
780
+ uint64_t timeout = static_cast <uint64_t >(1000000.0 * nextWakeup);
781
+ {
782
+ CONDITION_LOCKER (guardv, _cv);
783
+ _cv.wait (timeout);
784
+ }
771
785
}
772
786
}
773
787
}
0 commit comments