Skip to content

Fixed bug that Hyperf\Coordinator\Timer::tick() caps the callback by the default 10s timeout of Hyperf\Coroutine\Waiter - #7764

Merged
limingxinleo merged 5 commits into
hyperf:3.1from
huangdijia:fix/coordinator-timer-wait-timeout
Jun 17, 2026
Merged

limingxinleo merged 5 commits into
hyperf:3.1from
huangdijia:fix/coordinator-timer-wait-timeout

Conversation

@huangdijia

Copy link
Copy Markdown
Member

Summary

  • Pass -1 as the timeout to wait() inside Timer::tick(), so the callback is no longer capped by the implicit 10s timeout.

Background

v3.1.70 (#7761) wrapped the tick() callback in Hyperf\Coroutine\wait() to run it inside a properly managed coroutine context, but did not pass a timeout. Waiter::wait() falls back to its default popTimeout of 10 seconds when no timeout is given:

// src/coroutine/src/Waiter.php
if ($timeout === null) {
    $timeout = $this->popTimeout; // 10.0
}
$result = $channel->pop($timeout); // throws WaitTimeoutException after 10s

As a result, any tick() callback that runs longer than 10s gets cut off:

  • wait() throws a WaitTimeoutException,
  • tick() catches it and logs it as an error,
  • the still-running callback coroutine is orphaned (Swoole does not cancel it on channel timeout),
  • and its return value — e.g. Timer::STOP — is lost, so the timer may keep ticking.

Changes

  • src/coordinator/src/Timer.php: pass -1 to wait(...). Channel::pop(-1) waits indefinitely, so the callback always runs to completion and its return value is honored. -1 is the same "no timeout" sentinel already used by WaitGroup::wait(-1) and WaitConcurrent::wait(-1) in this codebase.
  • CHANGELOG-3.1.md: add a Fixed entry under v3.1.71 - TBD.

Test Plan

  • Existing src/coordinator/tests/TimerTest.php cases (testTick, testTickWhenReturnStop) keep passing — they use sub-millisecond callbacks, so the 10s timeout never engaged before or after.
  • Manually verified: a tick() callback that blocks for >10s now completes without a WaitTimeoutException being logged, and returning Timer::STOP still stops the timer.

Risks

  • Low. The only behavioral change is that long tick callbacks are no longer aborted at 10s — which is the intended behavior. Rollback: revert the one-line change.

@huangdijia
huangdijia requested a review from limingxinleo June 17, 2026 07:11
@huangdijia huangdijia changed the title Fixed bug that Hyperf\Coordinator\Timer::tick() caps the callback by the default 10s timeout of Hyperf\Coroutine\wait() Fixed bug that Hyperf\Coordinator\Timer::tick() caps the callback by the default 10s timeout of Hyperf\Coroutine\Waiter Jun 17, 2026
@limingxinleo
limingxinleo marked this pull request as ready for review June 17, 2026 07:47
@limingxinleo
limingxinleo merged commit 5a2a731 into hyperf:3.1 Jun 17, 2026
80 checks passed
@huangdijia
huangdijia deleted the fix/coordinator-timer-wait-timeout branch June 17, 2026 07:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants