Долгосрочный скрипт, который опрашивает внешний сервер с переменным таймером отката?

Я пишу долго работающий скрипт на основе библиотеки Amphp, который опрашивает внешний сервер для получения списка задач для запуска, а затем выполняет эти задачи.

В ответе от сервера будет таймер отката, который будет контролировать, когда скрипт выполняет следующий запрос.

Так как я очень плохо знаком с асинхронным программированием, то, что я пытаюсь, не работает.

Я попытался создать \Amp\repeat(), у которого была \Amp\Pause(1000), чтобы каждое повторение приостанавливалось на 1 секунду.

Вот мой тестовый код:

function test() {
    // http request goes here...

    echo 'server request '.microtime(true).PHP_EOL;

    // based on the server request, change the pause time
    yield new \Amp\Pause(1000);
}

Amp\execute(function () {
    \Amp\onSignal(SIGINT, function () {
        \Amp\stop();
    });

    \Amp\repeat(100, function () {
        yield from test();
    });
});

Я ожидал, что при каждом повторении функция test() будет останавливаться на 1 секунду после эхо, но вместо этого эхо запускалось каждые 100 мс (время повтора).

В прошлом я выполнял это с помощью цикла while и usleep(), но поскольку usleep() блокирует это, это побеждает цель.

Я использую PHP 7.0 и Amphp из мастер ветки github.

1 ответ

Решение

\Amp\repeat вызывает обратный вызов каждые 100 миллисекунд, независимо от того, когда обратный вызов завершается.

\Amp\execute(function () {
    /* onSignal handler here for example */

    new \Amp\Coroutine(function () {
        while (1) {
            /* dispatch request */
            echo 'server request '.microtime(true).PHP_EOL;
            yield new \Amp\Pause(100);
        }
    });
});

Это использует обычный цикл, который продолжается только 100 мс после последнего действия.

[Если я неправильно понял, что именно вы хотите, пожалуйста, обратите внимание в комментариях.]

Другие вопросы по тегам