Skip to content

Commit b6eaf72

Browse files
authored
Reduce complexity of DNSRecord (#915)
- Use constants for calculations in is_expired/is_stale/is_recent
1 parent aa71084 commit b6eaf72

3 files changed

Lines changed: 11 additions & 27 deletions

File tree

tests/services/test_info.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,7 @@ def test_service_info_rejects_expired_records(self):
187187
ttl,
188188
b'\x04ff=0\x04ci=3\x04sf=0\x0bsh=6fLM5A==',
189189
)
190-
expired_record.created = 1000
191-
expired_record._expiration_time = 1000
190+
expired_record.set_created_ttl(1000, 1)
192191
info.update_record(zc, now, expired_record)
193192
assert info.properties[b"ci"] == b"2"
194193
zc.close()

zeroconf/_dns.py

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@
3131
_CLASSES,
3232
_CLASS_MASK,
3333
_CLASS_UNIQUE,
34-
_EXPIRE_FULL_TIME_PERCENT,
35-
_EXPIRE_STALE_TIME_PERCENT,
36-
_RECENT_TIME_PERCENT,
3734
_TYPES,
3835
_TYPE_ANY,
3936
)
@@ -45,6 +42,11 @@
4542
_BASE_MAX_SIZE = _LEN_SHORT + _LEN_SHORT + _LEN_INT + _LEN_SHORT # type # class # ttl # length
4643
_NAME_COMPRESSION_MIN_SIZE = _LEN_BYTE * 2
4744

45+
_EXPIRE_FULL_TIME_MS = 1000
46+
_EXPIRE_STALE_TIME_MS = 500
47+
_RECENT_TIME_MS = 250
48+
49+
4850
if TYPE_CHECKING:
4951
# https://github.com/PyCQA/pylint/issues/3525
5052
from ._protocol import DNSIncoming, DNSOutgoing # pylint: disable=cyclic-import
@@ -154,7 +156,7 @@ class DNSRecord(DNSEntry):
154156

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

157-
__slots__ = ('ttl', 'created', '_expiration_time', '_stale_time', '_recent_time')
159+
__slots__ = ('ttl', 'created')
158160

159161
# TODO: Switch to just int ttl
160162
def __init__(
@@ -163,9 +165,6 @@ def __init__(
163165
super().__init__(name, type_, class_)
164166
self.ttl = ttl
165167
self.created = created or current_time_millis()
166-
self._expiration_time: Optional[float] = None
167-
self._stale_time: Optional[float] = None
168-
self._recent_time: Optional[float] = None
169168

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

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

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

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

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

227215
def write(self, out: 'DNSOutgoing') -> None: # pylint: disable=no-self-use
228216
"""Abstract method"""

zeroconf/const.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,7 @@
145145
_HAS_ONLY_A_TO_Z_NUM_HYPHEN_UNDERSCORE = re.compile(r'^[A-Za-z0-9\-\_]+$')
146146
_HAS_ASCII_CONTROL_CHARS = re.compile(r'[\x00-\x1f\x7f]')
147147

148-
_EXPIRE_FULL_TIME_PERCENT = 100
149-
_EXPIRE_STALE_TIME_PERCENT = 50
150148
_EXPIRE_REFRESH_TIME_PERCENT = 75
151-
_RECENT_TIME_PERCENT = 25
152149

153150
_LOCAL_TRAILER = '.local.'
154151
_TCP_PROTOCOL_LOCAL_TRAILER = '._tcp.local.'

0 commit comments

Comments
 (0)