daemon: updates to remove the delay for processing wlan changes along with code to support it

This commit is contained in:
Blake Harnden 2022-02-05 00:39:11 -08:00
parent 43737a42e4
commit efb97d1a5d
2 changed files with 24 additions and 51 deletions

View file

@ -343,14 +343,12 @@ class BasicRangeModel(WirelessModel):
:return: nothing :return: nothing
""" """
x, y, z = iface.node.position.get() x, y, z = iface.node.position.get()
self.iface_lock.acquire() with self.iface_lock:
self.iface_to_pos[iface] = (x, y, z) self.iface_to_pos[iface] = (x, y, z)
if x is None or y is None: if x is None or y is None:
self.iface_lock.release()
return return
for iface2 in self.iface_to_pos: for iface2 in self.iface_to_pos:
self.calclink(iface, iface2) self.calclink(iface, iface2)
self.iface_lock.release()
position_callback = set_position position_callback = set_position
@ -388,20 +386,15 @@ class BasicRangeModel(WirelessModel):
""" """
if iface == iface2: if iface == iface2:
return return
try: try:
x, y, z = self.iface_to_pos[iface] x, y, z = self.iface_to_pos[iface]
x2, y2, z2 = self.iface_to_pos[iface2] x2, y2, z2 = self.iface_to_pos[iface2]
if x2 is None or y2 is None: if x2 is None or y2 is None:
return return
d = self.calcdistance((x, y, z), (x2, y2, z2)) d = self.calcdistance((x, y, z), (x2, y2, z2))
# ordering is important, to keep the wlan._linked dict organized # ordering is important, to keep the wlan._linked dict organized
a = min(iface, iface2) a = min(iface, iface2)
b = max(iface, iface2) b = max(iface, iface2)
with self.wlan.linked_lock: with self.wlan.linked_lock:
linked = self.wlan.is_linked(a, b) linked = self.wlan.is_linked(a, b)
if d > self.range: if d > self.range:

View file

@ -4,7 +4,6 @@ Defines network nodes used within core.
import logging import logging
import threading import threading
import time
from collections import OrderedDict from collections import OrderedDict
from pathlib import Path from pathlib import Path
from queue import Queue from queue import Queue
@ -80,50 +79,32 @@ class NftablesQueue:
self.cmds: List[str] = [] self.cmds: List[str] = []
# list of WLANs requiring update # list of WLANs requiring update
self.updates: SetQueue = SetQueue() self.updates: SetQueue = SetQueue()
# timestamps of last WLAN update; this keeps track of WLANs that are
# using this queue
self.last_update_time: Dict["CoreNetwork", float] = {}
def start(self, net: "CoreNetwork") -> None: def start(self) -> None:
""" """
Start thread to listen for updates for the provided network. Start thread to listen for updates for the provided network.
:param net: network to start checking updates
:return: nothing :return: nothing
""" """
with self.lock: with self.lock:
self.last_update_time[net] = time.monotonic() if not self.running:
if self.running:
return
self.running = True self.running = True
self.run_thread = threading.Thread(target=self.run, daemon=True) self.run_thread = threading.Thread(target=self.run, daemon=True)
self.run_thread.start() self.run_thread.start()
def stop(self, net: "CoreNetwork") -> None: def stop(self) -> None:
""" """
Stop updates for network, when no networks remain, stop update thread. Stop updates for network, when no networks remain, stop update thread.
:param net: network to stop watching updates
:return: nothing :return: nothing
""" """
with self.lock: with self.lock:
self.last_update_time.pop(net, None) if self.running:
if self.last_update_time:
return
self.running = False self.running = False
if self.run_thread:
self.updates.put(None) self.updates.put(None)
self.run_thread.join() self.run_thread.join()
self.run_thread = None self.run_thread = None
def last_update(self, net: "CoreNetwork") -> float:
"""
Return the time elapsed since this network was last updated.
:param net: network node
:return: elapsed time
"""
now = time.monotonic()
last_update = self.last_update_time.setdefault(net, now)
return now - last_update
def run(self) -> None: def run(self) -> None:
""" """
Thread target that looks for networks needing update, and Thread target that looks for networks needing update, and
@ -136,17 +117,14 @@ class NftablesQueue:
net = self.updates.get() net = self.updates.get()
if net is None: if net is None:
break break
if not net.up:
self.last_update_time[net] = time.monotonic()
elif self.last_update(net) > self.rate:
with self.lock: with self.lock:
self.build_cmds(net) self.build_cmds(net)
self.commit(net) self.commit(net)
self.last_update_time[net] = time.monotonic()
def commit(self, net: "CoreNetwork") -> None: def commit(self, net: "CoreNetwork") -> None:
""" """
Commit changes to nftables for the provided network. Commit changes to nftables for the provided network.
:param net: network to commit nftables changes :param net: network to commit nftables changes
:return: nothing :return: nothing
""" """
@ -164,6 +142,7 @@ class NftablesQueue:
def update(self, net: "CoreNetwork") -> None: def update(self, net: "CoreNetwork") -> None:
""" """
Flag this network has an update, so the nftables chain will be rebuilt. Flag this network has an update, so the nftables chain will be rebuilt.
:param net: wlan network :param net: wlan network
:return: nothing :return: nothing
""" """
@ -182,6 +161,7 @@ class NftablesQueue:
def build_cmds(self, net: "CoreNetwork") -> None: def build_cmds(self, net: "CoreNetwork") -> None:
""" """
Inspect linked nodes for a network, and rebuild the nftables chain commands. Inspect linked nodes for a network, and rebuild the nftables chain commands.
:param net: network to build commands for :param net: network to build commands for
:return: nothing :return: nothing
""" """
@ -299,7 +279,7 @@ class CoreNetwork(CoreNetworkBase):
self.net_client.set_mtu(self.brname, self.mtu) self.net_client.set_mtu(self.brname, self.mtu)
self.has_nftables_chain = False self.has_nftables_chain = False
self.up = True self.up = True
nft_queue.start(self) nft_queue.start()
def shutdown(self) -> None: def shutdown(self) -> None:
""" """
@ -309,7 +289,7 @@ class CoreNetwork(CoreNetworkBase):
""" """
if not self.up: if not self.up:
return return
nft_queue.stop(self) nft_queue.stop()
try: try:
self.net_client.delete_bridge(self.brname) self.net_client.delete_bridge(self.brname)
if self.has_nftables_chain: if self.has_nftables_chain: