Skip to content

Commit 04356e7

Browse files
v1.18: Add in metrics for detecting Redundant Pulls (backport of #199) (#251)
Add in metrics for detecting Redundant Pulls (#199) (cherry picked from commit d49ceb0) Co-authored-by: Greg Cusack <[email protected]>
1 parent 585a413 commit 04356e7

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

gossip/src/cluster_info_metrics.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,11 @@ pub(crate) fn submit_gossip_stats(
315315
stats.process_pull_response_timeout.clear(),
316316
i64
317317
),
318+
(
319+
"num_redundant_pull_responses",
320+
crds_stats.num_redundant_pull_responses,
321+
i64
322+
),
318323
(
319324
"push_response_count",
320325
stats.push_response_count.clear(),

gossip/src/crds.rs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ pub(crate) struct CrdsDataStats {
115115
pub(crate) struct CrdsStats {
116116
pub(crate) pull: CrdsDataStats,
117117
pub(crate) push: CrdsDataStats,
118+
/// number of times a message was first received via a PullResponse
119+
/// and that message was later received via a PushMessage
120+
pub(crate) num_redundant_pull_responses: u64,
118121
}
119122

120123
/// This structure stores some local metadata associated with the CrdsValue
@@ -127,8 +130,10 @@ pub struct VersionedCrdsValue {
127130
pub(crate) local_timestamp: u64,
128131
/// value hash
129132
pub(crate) value_hash: Hash,
130-
/// Number of times duplicates of this value are recevied from gossip push.
131-
num_push_dups: u8,
133+
/// None -> value upserted by GossipRoute::{LocalMessage,PullRequest}
134+
/// Some(0) -> value upserted by GossipRoute::PullResponse
135+
/// Some(k) if k > 0 -> value upserted by GossipRoute::PushMessage w/ k - 1 push duplicates
136+
num_push_recv: Option<u8>,
132137
}
133138

134139
#[derive(Clone, Copy, Default)]
@@ -147,14 +152,21 @@ impl Cursor {
147152
}
148153

149154
impl VersionedCrdsValue {
150-
fn new(value: CrdsValue, cursor: Cursor, local_timestamp: u64) -> Self {
155+
fn new(value: CrdsValue, cursor: Cursor, local_timestamp: u64, route: GossipRoute) -> Self {
151156
let value_hash = hash(&serialize(&value).unwrap());
157+
let num_push_recv = match route {
158+
GossipRoute::LocalMessage => None,
159+
GossipRoute::PullRequest => None,
160+
GossipRoute::PullResponse => Some(0),
161+
GossipRoute::PushMessage(_) => Some(1),
162+
};
163+
152164
VersionedCrdsValue {
153165
ordinal: cursor.ordinal(),
154166
value,
155167
local_timestamp,
156168
value_hash,
157-
num_push_dups: 0u8,
169+
num_push_recv,
158170
}
159171
}
160172
}
@@ -222,7 +234,7 @@ impl Crds {
222234
) -> Result<(), CrdsError> {
223235
let label = value.label();
224236
let pubkey = value.pubkey();
225-
let value = VersionedCrdsValue::new(value, self.cursor, now);
237+
let value = VersionedCrdsValue::new(value, self.cursor, now, route);
226238
match self.table.entry(label) {
227239
Entry::Vacant(entry) => {
228240
self.stats.lock().unwrap().record_insert(&value, route);
@@ -303,8 +315,12 @@ impl Crds {
303315
Err(CrdsError::InsertFailed)
304316
} else if matches!(route, GossipRoute::PushMessage(_)) {
305317
let entry = entry.get_mut();
306-
entry.num_push_dups = entry.num_push_dups.saturating_add(1);
307-
Err(CrdsError::DuplicatePush(entry.num_push_dups))
318+
if entry.num_push_recv == Some(0) {
319+
self.stats.lock().unwrap().num_redundant_pull_responses += 1;
320+
}
321+
let num_push_dups = entry.num_push_recv.unwrap_or_default();
322+
entry.num_push_recv = Some(num_push_dups.saturating_add(1));
323+
Err(CrdsError::DuplicatePush(num_push_dups))
308324
} else {
309325
Err(CrdsError::InsertFailed)
310326
}
@@ -1450,8 +1466,9 @@ mod tests {
14501466
#[allow(clippy::neg_cmp_op_on_partial_ord)]
14511467
fn test_equal() {
14521468
let val = CrdsValue::new_unsigned(CrdsData::LegacyContactInfo(ContactInfo::default()));
1453-
let v1 = VersionedCrdsValue::new(val.clone(), Cursor::default(), 1);
1454-
let v2 = VersionedCrdsValue::new(val, Cursor::default(), 1);
1469+
let v1 =
1470+
VersionedCrdsValue::new(val.clone(), Cursor::default(), 1, GossipRoute::LocalMessage);
1471+
let v2 = VersionedCrdsValue::new(val, Cursor::default(), 1, GossipRoute::LocalMessage);
14551472
assert_eq!(v1, v2);
14561473
assert!(!(v1 != v2));
14571474
assert!(!overrides(&v1.value, &v2));
@@ -1467,6 +1484,7 @@ mod tests {
14671484
))),
14681485
Cursor::default(),
14691486
1, // local_timestamp
1487+
GossipRoute::LocalMessage,
14701488
);
14711489
let v2 = VersionedCrdsValue::new(
14721490
{
@@ -1476,6 +1494,7 @@ mod tests {
14761494
},
14771495
Cursor::default(),
14781496
1, // local_timestamp
1497+
GossipRoute::LocalMessage,
14791498
);
14801499

14811500
assert_eq!(v1.value.label(), v2.value.label());
@@ -1501,6 +1520,7 @@ mod tests {
15011520
))),
15021521
Cursor::default(),
15031522
1, // local_timestamp
1523+
GossipRoute::LocalMessage,
15041524
);
15051525
let v2 = VersionedCrdsValue::new(
15061526
CrdsValue::new_unsigned(CrdsData::LegacyContactInfo(ContactInfo::new_localhost(
@@ -1509,6 +1529,7 @@ mod tests {
15091529
))),
15101530
Cursor::default(),
15111531
1, // local_timestamp
1532+
GossipRoute::LocalMessage,
15121533
);
15131534
assert_eq!(v1.value.label(), v2.value.label());
15141535
assert!(overrides(&v1.value, &v2));
@@ -1527,6 +1548,7 @@ mod tests {
15271548
))),
15281549
Cursor::default(),
15291550
1, // local_timestamp
1551+
GossipRoute::LocalMessage,
15301552
);
15311553
let v2 = VersionedCrdsValue::new(
15321554
CrdsValue::new_unsigned(CrdsData::LegacyContactInfo(ContactInfo::new_localhost(
@@ -1535,6 +1557,7 @@ mod tests {
15351557
))),
15361558
Cursor::default(),
15371559
1, // local_timestamp
1560+
GossipRoute::LocalMessage,
15381561
);
15391562
assert_ne!(v1, v2);
15401563
assert!(!(v1 == v2));

0 commit comments

Comments
 (0)