public function run()
    {
        $count = 0;
        $start = microtime(true);

        while (true) {
            try {
                return call_user_func($this->callable);
            } catch (\Throwable $e) {
                // Check exception
                if (!$e instanceof $this->exceptionType) {
                    throw $e;
                }

                // Check timeout
                if ($this->timeout > -1 && microtime(true) - $start > ($this->timeout / self::SECONDS)) {
                    throw $e;
                }

                // Check count
                if ($this->count > -1 && ++$count >= $this->count) {
                    throw $e;
                }

                // Before pause hook
                if (array_key_exists(self::BEFORE_PAUSE_HOOK, $this->hooks)) {
                    call_user_func($this->hooks[self::BEFORE_PAUSE_HOOK], $e);
                }

                usleep($this->pause);

                // After pause hook
                if (array_key_exists(self::AFTER_PAUSE_HOOK, $this->hooks)) {
                    call_user_func($this->hooks[self::AFTER_PAUSE_HOOK], $e);
                }
            }
        }
    }