Skip to content

Commit 43b5e1a

Browse files
authored
CPU Spike because of redundant and flooded keyspace notifis handled (sonic-net#230)
**- What I did** Fixes [sonic-net#8293](sonic-net#8293) **- How I did it** Accumulated all the older notifications and did act only upon the latest notification discarding the others
1 parent 4d6bb79 commit 43b5e1a

File tree

2 files changed

+48
-9
lines changed

2 files changed

+48
-9
lines changed

src/sonic_ax_impl/mibs/ieee802_1ab.py

+19-9
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,18 @@ def poll_lldp_entry_updates(pubsub):
9696
return ret
9797
return data, interface, if_index
9898

99+
def get_latest_notification(pubsub):
100+
"""
101+
Fetches the latest notification recorded on a lldp entry.
102+
"""
103+
latest_update_map = {}
104+
while True:
105+
data, interface, if_index = poll_lldp_entry_updates(pubsub)
106+
if not data:
107+
break
108+
latest_update_map[interface] = (data, if_index)
109+
return latest_update_map
110+
99111
def parse_sys_capability(sys_cap):
100112
return bytearray([int (x, 16) for x in sys_cap.split()])
101113

@@ -542,19 +554,17 @@ def _update_per_namespace_data(self, pubsub):
542554
"""
543555
Listen to updates in APP DB, update local cache
544556
"""
545-
while True:
546-
data, interface, if_index = poll_lldp_entry_updates(pubsub)
547-
548-
if not data:
549-
break
550-
557+
event_cache = get_latest_notification(pubsub)
558+
for interface in event_cache:
559+
data = event_cache[interface][0]
560+
if_index = event_cache[interface][1]
561+
551562
if "set" in data:
552563
self.update_rem_if_mgmt(if_index, interface)
553564
elif "del" in data:
554-
# some remote data about that neighbor is gone, del it and try to query again
565+
# if del is the latest notification, then delete it from the local cache
555566
self.if_range = [sub_oid for sub_oid in self.if_range if sub_oid[0] != if_index]
556-
self.update_rem_if_mgmt(if_index, interface)
557-
567+
558568
def update_data(self):
559569
for i in range(len(self.db_conn)):
560570
if not self.pubsub[i]:

tests/test_lldp.py

+29
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717
from ax_interface.pdu import PDU, PDUHeader
1818
from ax_interface.mib import MIBTable
1919
from sonic_ax_impl.mibs import ieee802_1ab
20+
from mock import patch
2021

22+
def mock_poll_lldp_notif(mock_lldp_polled_entries):
23+
if not mock_lldp_polled_entries:
24+
return None, None, None
25+
return mock_lldp_polled_entries.pop(0)
2126

2227
class TestLLDPMIB(TestCase):
2328
@classmethod
@@ -314,3 +319,27 @@ def test_getnextpdu_lldpRemSysCapEnabled(self):
314319
self.assertEqual(value0.type_, ValueType.OCTET_STRING)
315320
self.assertEqual(str(value0.name), str(ObjectIdentifier(12, 0, 1, 0, (1, 0, 8802, 1, 1, 2, 1, 4, 1, 1, 12, 1, 1))))
316321
self.assertEqual(str(value0.data), "\x28\x00")
322+
323+
@patch("sonic_ax_impl.mibs.ieee802_1ab.poll_lldp_entry_updates", mock_poll_lldp_notif)
324+
def test_get_latest_notification(self):
325+
mock_lldp_polled_entries = []
326+
mock_lldp_polled_entries.extend([("hset", "Ethernet0", "123"),
327+
("hset", "Ethernet4", "124"),
328+
("del", "Ethernet4", "124"),
329+
("del", "Ethernet8", "125"),
330+
("hset", "Ethernet8", "125"),
331+
("hset", "Ethernet4", "124"),
332+
("del", "Ethernet0", "123"),
333+
("hset", "Ethernet12", "126"),
334+
("del", "Ethernet12", "126"),
335+
("hset", "Ethernet0", "123"),
336+
("del", "Ethernet16", "127")])
337+
event_cache = ieee802_1ab.get_latest_notification(mock_lldp_polled_entries)
338+
expect = {"Ethernet0" : ("hset", "123"),
339+
"Ethernet4" : ("hset", "124"),
340+
"Ethernet8" : ("hset", "125"),
341+
"Ethernet12" : ("del", "126"),
342+
"Ethernet16" : ("del", "127")}
343+
for key in expect.keys():
344+
assert key in event_cache
345+
self.assertEqual(expect[key], event_cache[key])

0 commit comments

Comments
 (0)