master

laravel/framework

Last updated at: 29/12/2023 09:25

Timebox.php

TLDR

The Timebox class in the Illuminate\Support namespace provides a mechanism for executing a callback within a specified time limit. It allows setting whether the timebox can return early or not.

Methods

call

Invokes the given callback within the specified time limit in microseconds. If the callback throws an exception, it is caught and rethrown after the time limit is reached. The method returns the result of the callback.

returnEarly

Sets the earlyReturn property of the Timebox instance to true, indicating that the timebox can return early.

dontReturnEarly

Sets the earlyReturn property of the Timebox instance to false, indicating that the timebox cannot return early.

usleep

Sleeps for the specified number of microseconds.

<?php

namespace Illuminate\Support;

use Throwable;

class Timebox
{
    /**
     * Indicates if the timebox is allowed to return early.
     *
     * @var bool
     */
    public $earlyReturn = false;

    /**
     * Invoke the given callback within the specified timebox minimum.
     *
     * @template TCallReturnType
     *
     * @param  (callable($this): TCallReturnType)  $callback
     * @param  int  $microseconds
     * @return TCallReturnType
     */
    public function call(callable $callback, int $microseconds)
    {
        $exception = null;

        $start = microtime(true);

        try {
            $result = $callback($this);
        } catch (Throwable $caught) {
            $exception = $caught;
        }

        $remainder = intval($microseconds - ((microtime(true) - $start) * 1000000));

        if (! $this->earlyReturn && $remainder > 0) {
            $this->usleep($remainder);
        }

        if ($exception) {
            throw $exception;
        }

        return $result;
    }

    /**
     * Indicate that the timebox can return early.
     *
     * @return $this
     */
    public function returnEarly()
    {
        $this->earlyReturn = true;

        return $this;
    }

    /**
     * Indicate that the timebox cannot return early.
     *
     * @return $this
     */
    public function dontReturnEarly()
    {
        $this->earlyReturn = false;

        return $this;
    }

    /**
     * Sleep for the specified number of microseconds.
     *
     * @param  int  $microseconds
     * @return void
     */
    protected function usleep(int $microseconds)
    {
        Sleep::usleep($microseconds);
    }
}