The is_failed() skip exists in two execution paths: the heap loop in call()
and should_skip_item_() (defer queue / delay:0). The previous commit only
exempted SELF_POINTER items from the heap-path check, so on multi-threaded
platforms a delay:0 continuation whose host component had failed would still
be silently dropped.
Extract a single is_item_failed_() helper (with the SELF_POINTER exemption)
and use it from both paths so they cannot drift again.
Add an integration test that schedules a delay from a component that marks
itself failed and asserts the continuation still fires (verified to fail
without the exemption).
A blocking operation that runs inside a deferred scheduler continuation
(e.g. after a delay in a script/automation) was reported as:
<null> took a long time for an operation (83 ms), max is 30 ms
Two problems:
* The DelayAction continuation carries no component (since #16129 dropped
Component inheritance), so the warning had nothing to name and printed
"<null>". Telling the user an anonymous delay action is blocking is not
useful; naming the component that hosts the automation is.
* The threshold was hardcoded to "30 ms" but the real default is 50 ms
(WARN_IF_BLOCKING_OVER_CS) and is adaptive per component.
DelayAction now records App.get_current_component() on the scheduler item,
so the warning names the component whose automation chain hit the delay
(falling back to "a scheduled task" when there is genuinely no current
component). This propagates across chained delays because the scheduler
restores the item's component as the current component before each callback.
For SELF_POINTER items the stored component is log-attribution only: the
key (the caller's `this`) is globally unique, so matches_item_locked_
ignores the component when matching and the is_failed() skip is bypassed.
This keeps delay cancellation (restart/parallel/stop) and always-fire
semantics unchanged.
The warning now reports the real (pre-ratchet) threshold instead of the
stale "30 ms".
Adds an integration test reproducing the deferred-block path via an
interval + delay + busy lambda and asserting the warning names a component
and reports "max is 50 ms".
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>