ensure QA configmap is updated for long running QA runs: (#1865)

- add a 'expire_at_duration_seconds' which is 75% of actual presign
duration time, or <25% remaining until presigned URL actually expires to
ensure presigned URLs are updated early than when they actually expire
- set cached expireAt time to the renew at time for more frequent
updates
- update QA configmap in place with updated presigned URLs when expireAt
time is reached
- mount qa config volume under /tmp/qa/ without subPath to get automatic
updates, which crawler will handle
- tests: fix qa test typo (from main)
- fixes #1864
This commit is contained in:
Ilya Kreymer 2024-06-12 10:51:35 -07:00 committed by GitHub
parent 9d69001c23
commit fa6627ce70
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 35 additions and 9 deletions

View File

@ -64,7 +64,8 @@ class BaseCrawlOps:
background_job_ops: BackgroundJobOps
page_ops: PageOps
presign_duration: int
presign_duration_seconds: int
expire_at_duration_seconds: int
def __init__(
self,
@ -95,6 +96,9 @@ class BaseCrawlOps:
min(presign_duration_minutes, PRESIGN_MINUTES_MAX) * 60
)
# renew when <25% of time remaining
self.expire_at_duration_seconds = int(self.presign_duration_seconds * 0.75)
def set_page_ops(self, page_ops):
"""set page ops reference"""
self.page_ops = page_ops
@ -434,7 +438,7 @@ class BaseCrawlOps:
print("no files")
return []
delta = timedelta(seconds=self.presign_duration_seconds)
delta = timedelta(seconds=self.expire_at_duration_seconds)
out_files = []

View File

@ -325,8 +325,15 @@ class CrawlOperator(BaseOperator):
qa_source_crawl_id = params["qa_source_crawl_id"]
name = f"qa-replay-{qa_source_crawl_id}"
if name in children[CMAP]:
return [children[CMAP][name]]
configmap = children[CMAP].get(name)
if configmap and not self._qa_configmap_update_needed(name, configmap):
metadata = configmap["metadata"]
configmap["metadata"] = {
"name": metadata["name"],
"namespace": metadata["namespace"],
"labels": metadata["labels"],
}
return [configmap]
crawl_replay = await self.crawl_ops.get_internal_crawl_out(qa_source_crawl_id)
@ -364,6 +371,22 @@ class CrawlOperator(BaseOperator):
return self.load_from_yaml("crawler.yaml", params)
def _qa_configmap_update_needed(self, name, configmap):
try:
now = dt_now()
resources = json.loads(configmap["data"]["qa-config.json"])["resources"]
for resource in resources:
expire_at = datetime.fromisoformat(resource["expireAt"])
if expire_at <= now:
print(f"Refreshing QA configmap for QA run: {name}")
return True
# pylint: disable=broad-exception-caught
except Exception as e:
print(e)
return False
# pylint: disable=too-many-arguments
async def _resolve_scale(
self,

View File

@ -383,7 +383,7 @@ def test_run_qa_not_running(
count = 0
while count < MAX_ATTEMPTS:
r = requests.get(
f"{API_PREFIX}/orgs/{default_org_id}/crawls/{crawler_crawl_id}/activeQA",
f"{API_PREFIX}/orgs/{default_org_id}/crawls/{crawler_crawl_id}/qa/activeQA",
headers=crawler_auth_headers,
)
data = r.json()

View File

@ -124,7 +124,7 @@ spec:
- {{ redis_url }}
{% if qa_source_crawl_id %}
- --qaSource
- /tmp/qa-config.json
- /tmp/qa/qa-config.json
{% elif profile_filename %}
- --profile
- "@{{ profile_filename }}"
@ -137,8 +137,7 @@ spec:
{% if qa_source_crawl_id %}
- name: qa-config
mountPath: /tmp/qa-config.json
subPath: qa-config.json
mountPath: /tmp/qa/
readOnly: True
{% endif %}

View File

@ -23,7 +23,7 @@ spec:
- apiVersion: v1
resource: configmaps
updateStrategy:
method: OnDelete
method: InPlace
hooks:
sync: