Addresses @EnxDev's review on #41133:
- Soft timeouts now abort the export instead of being caught per chart: the
per-chart SoftTimeLimitExceeded handler (and screenshot.py's broad except)
re-raise, so the outer handler emails a failure and runs cleanup rather than
running to the hard limit (leaking temp files, holding the lock). Removes the
now-dead ERROR_TIMEOUT reason.
- Concurrency guard uses a shared, atomic DistributedLock (Redis when
configured, metadata DB otherwise) instead of cache_manager.cache, which is a
no-op under the default NullCache and process-local under SimpleCache. The
lock is released if apply_async fails so a broker outage can't block exports
until the TTL expires.
- boto3 is declared via a new `excel-export` optional extra; superset.utils.s3
raises an actionable install hint when it is missing.
- "Export Images to Excel" is gated on the webdriver screenshot feature flags
(it renders via the headless webdriver); documents EXCEL_EXPORT_TABLE_VIZ_TYPES
and the image mode in the config docs and UPDATING.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>