Skip to content

Commit 08c1d03

Browse files
eschuthoclaude
andauthored
fix(screenshots): Only cache thumbnails when image generation succeeds (#36126)
Co-authored-by: Claude <[email protected]>
1 parent a2267d8 commit 08c1d03

File tree

2 files changed

+425
-6
lines changed

2 files changed

+425
-6
lines changed

superset/utils/screenshots.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,22 @@ def is_error_cache_ttl_expired(self) -> bool:
150150
datetime.now() - datetime.fromisoformat(self.get_timestamp())
151151
).total_seconds() > error_cache_ttl
152152

153+
def is_computing_stale(self) -> bool:
154+
"""Check if a COMPUTING status is stale (task likely failed or stuck)."""
155+
# Use the same TTL as error cache - if computing takes longer than this,
156+
# it's likely stuck and should be retried
157+
computing_ttl = app.config["THUMBNAIL_ERROR_CACHE_TTL"]
158+
return (
159+
datetime.now() - datetime.fromisoformat(self.get_timestamp())
160+
).total_seconds() >= computing_ttl
161+
153162
def should_trigger_task(self, force: bool = False) -> bool:
154163
return (
155164
force
156165
or self.status == StatusValues.PENDING
157166
or (self.status == StatusValues.ERROR and self.is_error_cache_ttl_expired())
167+
or (self.status == StatusValues.COMPUTING and self.is_computing_stale())
168+
or (self.status == StatusValues.UPDATED and self._image is None)
158169
)
159170

160171

@@ -264,10 +275,7 @@ def compute_and_cache( # pylint: disable=too-many-arguments
264275
"""
265276
cache_key = cache_key or self.get_cache_key(window_size, thumb_size)
266277
cache_payload = self.get_from_cache_key(cache_key) or ScreenshotCachePayload()
267-
if (
268-
cache_payload.status in [StatusValues.COMPUTING, StatusValues.UPDATED]
269-
and not force
270-
):
278+
if not cache_payload.should_trigger_task(force=force):
271279
logger.info(
272280
"Skipping compute - already processed for thumbnail: %s", cache_key
273281
)
@@ -277,7 +285,6 @@ def compute_and_cache( # pylint: disable=too-many-arguments
277285
thumb_size = thumb_size or self.thumb_size
278286
logger.info("Processing url for thumbnail: %s", cache_key)
279287
cache_payload.computing()
280-
self.cache.set(cache_key, cache_payload.to_dict())
281288
image = None
282289
# Assuming all sorts of things can go wrong with Selenium
283290
try:
@@ -295,10 +302,12 @@ def compute_and_cache( # pylint: disable=too-many-arguments
295302
cache_payload.error()
296303
image = None
297304

305+
# Cache the result (success or error) to avoid immediate retries
298306
if image:
299-
logger.info("Caching thumbnail: %s", cache_key)
300307
with event_logger.log_context(f"screenshot.cache.{self.thumbnail_type}"):
301308
cache_payload.update(image)
309+
310+
logger.info("Caching thumbnail: %s", cache_key)
302311
self.cache.set(cache_key, cache_payload.to_dict())
303312
logger.info("Updated thumbnail cache; Status: %s", cache_payload.get_status())
304313
return

0 commit comments

Comments
 (0)