Skip to content

Examples

github-actions[bot] edited this page Jul 14, 2026 · 1 revision

Примеры

Практические сценарии использования cloudcastle/clock. Запускаемый файл — examples/basic.php в репозитории.

Тестируемый retry с backoff

use CloudCastle\Clock\Contract\SleepableClockInterface;

final class ApiRetrier
{
    public function __construct(private readonly SleepableClockInterface $clock) {}

    public function call(callable $attempt): mixed
    {
        foreach ([1.0, 2.0, 4.0] as $backoff) {
            try {
                return $attempt();
            } catch (TransportException) {
                $this->clock->sleep($backoff);
            }
        }

        return $attempt();
    }
}

// Прод: new ApiRetrier(SystemClock::utc()) — реальные паузы.
// Тест: new ApiRetrier(MockClock::fromUtcNow()) — три ретрая за миллисекунды.

Ключ кэша по минутному окну

use CloudCastle\Clock\SystemClock;
use CloudCastle\Clock\TruncatingClock;

$window = TruncatingClock::toMinute(SystemClock::utc());
$cacheKey = 'rates:' . $window->timestamp();   // одинаков для всех запросов минуты

«Завтра» на стенде без перевода часов

use CloudCastle\Clock\OffsetClock;
use CloudCastle\Clock\SystemClock;

$clock = OffsetClock::aheadBy(SystemClock::utc(), 86_400.0);
$notifier->sendIfDue($clock->now());           // система живёт в завтрашнем дне

Сутки за 24 минуты: симуляция биллинга

use CloudCastle\Clock\ScaledClock;
use CloudCastle\Clock\SystemClock;

$fast = new ScaledClock(SystemClock::utc(), 60.0);   // 1 реальная секунда = 1 виртуальная минута

while ($fast->now() < $endOfDay) {
    $billing->tick($fast->now());
}

Замер этапов консольной команды

use CloudCastle\Clock\Stopwatch;

$watch = Stopwatch::start();

importUsers();
$watch->lap('пользователи');

importOrders();
$watch->lap('заказы');

printf("Готово за %.1f мс\n", $watch->stop() * 1000);

Дедлайн, неуязвимый к переводу часов

use CloudCastle\Clock\MonotonicClock;

$clock = new MonotonicClock();
$deadline = $clock->microtime() + 30.0;

while ($clock->microtime() < $deadline) {
    if ($job->poll()) {
        return true;
    }

    usleep(100_000);
}

throw new TimeoutException();

Чужие часы в наших декораторах

use CloudCastle\Clock\OffsetClock;
use CloudCastle\Clock\PsrClockAdapter;

$foreign = new \Lcobucci\Clock\SystemClock(new DateTimeZone('UTC'));
$tomorrow = new OffsetClock(PsrClockAdapter::wrap($foreign), 86_400.0);

Снимок момента для управляемого сдвига

$frozen = SystemClock::utc()->freeze();   // «сейчас» остановлено

$frozen->advance(3600.0);                 // и управляемо сдвигается

Clone this wiki locally