Skip to content

Commit

Permalink
Reduce complexity of DNSRecord (#915)
Browse files Browse the repository at this point in the history
- Use constants for calculations in is_expired/is_stale/is_recent
  • Loading branch information
bdraco authored Jul 18, 2021
1 parent aa71084 commit b6eaf72
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 27 deletions.
3 changes: 1 addition & 2 deletions tests/services/test_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,7 @@ def test_service_info_rejects_expired_records(self):
ttl,
b'\x04ff=0\x04ci=3\x04sf=0\x0bsh=6fLM5A==',
)
expired_record.created = 1000
expired_record._expiration_time = 1000
expired_record.set_created_ttl(1000, 1)
info.update_record(zc, now, expired_record)
assert info.properties[b"ci"] == b"2"
zc.close()
Expand Down
32 changes: 10 additions & 22 deletions zeroconf/_dns.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@
_CLASSES,
_CLASS_MASK,
_CLASS_UNIQUE,
_EXPIRE_FULL_TIME_PERCENT,
_EXPIRE_STALE_TIME_PERCENT,
_RECENT_TIME_PERCENT,
_TYPES,
_TYPE_ANY,
)
Expand All @@ -45,6 +42,11 @@
_BASE_MAX_SIZE = _LEN_SHORT + _LEN_SHORT + _LEN_INT + _LEN_SHORT # type # class # ttl # length
_NAME_COMPRESSION_MIN_SIZE = _LEN_BYTE * 2

_EXPIRE_FULL_TIME_MS = 1000
_EXPIRE_STALE_TIME_MS = 500
_RECENT_TIME_MS = 250


if TYPE_CHECKING:
# https://github.com/PyCQA/pylint/issues/3525
from ._protocol import DNSIncoming, DNSOutgoing # pylint: disable=cyclic-import
Expand Down Expand Up @@ -154,7 +156,7 @@ class DNSRecord(DNSEntry):

"""A DNS record - like a DNS entry, but has a TTL"""

__slots__ = ('ttl', 'created', '_expiration_time', '_stale_time', '_recent_time')
__slots__ = ('ttl', 'created')

# TODO: Switch to just int ttl
def __init__(
Expand All @@ -163,9 +165,6 @@ def __init__(
super().__init__(name, type_, class_)
self.ttl = ttl
self.created = created or current_time_millis()
self._expiration_time: Optional[float] = None
self._stale_time: Optional[float] = None
self._recent_time: Optional[float] = None

def __eq__(self, other: Any) -> bool: # pylint: disable=no-self-use
"""Abstract method"""
Expand All @@ -189,27 +188,19 @@ def get_expiration_time(self, percent: int) -> float:
# TODO: Switch to just int here
def get_remaining_ttl(self, now: float) -> Union[int, float]:
"""Returns the remaining TTL in seconds."""
if self._expiration_time is None:
self._expiration_time = self.get_expiration_time(_EXPIRE_FULL_TIME_PERCENT)
return max(0, millis_to_seconds(self._expiration_time - now))
return max(0, millis_to_seconds((self.created + (_EXPIRE_FULL_TIME_MS * self.ttl)) - now))

def is_expired(self, now: float) -> bool:
"""Returns true if this record has expired."""
if self._expiration_time is None:
self._expiration_time = self.get_expiration_time(_EXPIRE_FULL_TIME_PERCENT)
return self._expiration_time <= now
return self.created + (_EXPIRE_FULL_TIME_MS * self.ttl) <= now

def is_stale(self, now: float) -> bool:
"""Returns true if this record is at least half way expired."""
if self._stale_time is None:
self._stale_time = self.get_expiration_time(_EXPIRE_STALE_TIME_PERCENT)
return self._stale_time <= now
return self.created + (_EXPIRE_STALE_TIME_MS * self.ttl) <= now

def is_recent(self, now: float) -> bool:
"""Returns true if the record more than one quarter of its TTL remaining."""
if self._recent_time is None:
self._recent_time = self.get_expiration_time(_RECENT_TIME_PERCENT)
return self._recent_time > now
return self.created + (_RECENT_TIME_MS * self.ttl) > now

def reset_ttl(self, other: 'DNSRecord') -> None:
"""Sets this record's TTL and created time to that of
Expand All @@ -220,9 +211,6 @@ def set_created_ttl(self, created: float, ttl: Union[float, int]) -> None:
"""Set the created and ttl of a record."""
self.created = created
self.ttl = ttl
self._expiration_time = None
self._stale_time = None
self._recent_time = None

def write(self, out: 'DNSOutgoing') -> None: # pylint: disable=no-self-use
"""Abstract method"""
Expand Down
3 changes: 0 additions & 3 deletions zeroconf/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,7 @@
_HAS_ONLY_A_TO_Z_NUM_HYPHEN_UNDERSCORE = re.compile(r'^[A-Za-z0-9\-\_]+$')
_HAS_ASCII_CONTROL_CHARS = re.compile(r'[\x00-\x1f\x7f]')

_EXPIRE_FULL_TIME_PERCENT = 100
_EXPIRE_STALE_TIME_PERCENT = 50
_EXPIRE_REFRESH_TIME_PERCENT = 75
_RECENT_TIME_PERCENT = 25

_LOCAL_TRAILER = '.local.'
_TCP_PROTOCOL_LOCAL_TRAILER = '._tcp.local.'
Expand Down

0 comments on commit b6eaf72

Please sign in to comment.