Skip to content

Commit 8cee860

Browse files
tylfinP403n1x87
andauthored
chore(rc): avoid expires parsing [backport 2.21] (#13826)
We avoid parsing the expires string into a date-time object. Currently the value is not used, so we avoid calls to `_strptime`, which make use of a global lock in its internal implementation. Refs: [DEBUG-4109](https://datadoghq.atlassian.net/browse/DEBUG-4109) ## Checklist - [x] PR author has checked that all the criteria below are met - The PR description includes an overview of the change - The PR description articulates the motivation for the change - The change includes tests OR the PR description describes a testing strategy - The PR description notes risks associated with the change, if any - Newly-added code is easy to change - The change follows the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) - The change includes or references documentation updates if necessary - Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [ ] Reviewer has checked that all the criteria below are met - Title is accurate - All changes are related to the pull request's stated goal - Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes - Testing strategy adequately addresses listed risks - Newly-added code is easy to change - Release note makes sense to a user of the library - If necessary, author has acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment - Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting) [DEBUG-4109]: https://datadoghq.atlassian.net/browse/DEBUG-4109?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [DEBUG-4109]: https://datadoghq.atlassian.net/browse/DEBUG-4109?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ Co-authored-by: Gabriele N. Tornetta <[email protected]>
1 parent eeb528b commit 8cee860

File tree

3 files changed

+4
-53
lines changed

3 files changed

+4
-53
lines changed

ddtrace/internal/remoteconfig/client.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import base64
22
import dataclasses
3-
from datetime import datetime
43
import enum
54
import hashlib
65
import json
@@ -30,7 +29,6 @@
3029
from ddtrace.internal.packages import is_distribution_available
3130
from ddtrace.internal.remoteconfig.constants import REMOTE_CONFIG_AGENT_ENDPOINT
3231
from ddtrace.internal.service import ServiceStatus
33-
from ddtrace.internal.utils.time import parse_isoformat
3432

3533
from ..utils.formats import parse_tags_str
3634
from ..utils.version import _pep440_to_semver
@@ -121,16 +119,14 @@ class Root:
121119
_type: str
122120
spec_version: str
123121
consistent_snapshot: bool
124-
expires: datetime
122+
expires: str
125123
keys: Mapping[str, Key]
126124
roles: Mapping[str, Role]
127125
version: int
128126

129127
def __post_init__(self):
130128
if self._type != "root":
131129
raise ValueError("Root: invalid root type")
132-
if isinstance(self.expires, str):
133-
self.expires = parse_isoformat(self.expires)
134130
for k, v in self.keys.items():
135131
if isinstance(v, dict):
136132
self.keys[k] = Key(**v)
@@ -163,7 +159,7 @@ class TargetDesc:
163159
class Targets:
164160
_type: str
165161
custom: Mapping[str, Any]
166-
expires: datetime
162+
expires: str
167163
spec_version: str
168164
targets: Mapping[str, TargetDesc]
169165
version: int
@@ -173,8 +169,6 @@ def __post_init__(self):
173169
raise ValueError("Targets: invalid targets type")
174170
if self.spec_version not in ("1.0", "1.0.0"):
175171
raise ValueError("Targets: invalid spec version")
176-
if isinstance(self.expires, str):
177-
self.expires = parse_isoformat(self.expires)
178172
for k, v in self.targets.items():
179173
if isinstance(v, dict):
180174
self.targets[k] = TargetDesc(**v)

ddtrace/internal/utils/time.py

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from datetime import datetime
21
import time
32
from types import TracebackType
43
from typing import Optional
@@ -10,20 +9,6 @@
109
log = get_logger(__name__)
1110

1211

13-
def parse_isoformat(date):
14-
# type: (str) -> Optional[datetime]
15-
if date.endswith("Z"):
16-
try:
17-
return datetime.strptime(date, "%Y-%m-%dT%H:%M:%S.%fZ")
18-
except ValueError:
19-
return datetime.strptime(date, "%Y-%m-%dT%H:%M:%SZ")
20-
try:
21-
return datetime.fromisoformat(date)
22-
except (ValueError, IndexError):
23-
log.debug("unsupported isoformat: %s", date)
24-
return None
25-
26-
2712
class StopWatch(object):
2813
"""A simple timer/stopwatch helper class.
2914
@@ -57,7 +42,7 @@ def elapsed(self) -> float:
5742
"""
5843
# NOTE: datetime.timedelta does not support nanoseconds, so keep a float here
5944
if self._started_at is None:
60-
raise RuntimeError("Can not get the elapsed time of a stopwatch" " if it has not been started/stopped")
45+
raise RuntimeError("Can not get the elapsed time of a stopwatch if it has not been started/stopped")
6146
if self._stopped_at is None:
6247
now = time.monotonic()
6348
else:
@@ -80,7 +65,7 @@ def stop(self):
8065
# type: () -> StopWatch
8166
"""Stops the watch."""
8267
if self._started_at is None:
83-
raise RuntimeError("Can not stop a stopwatch that has not been" " started")
68+
raise RuntimeError("Can not stop a stopwatch that has not been started")
8469
self._stopped_at = time.monotonic()
8570
return self
8671

tests/internal/test_utils_time.py

Lines changed: 0 additions & 28 deletions
This file was deleted.

0 commit comments

Comments
 (0)