Zakładając chcesz użyć żądania HTTP, masz kilka opcji, należy ustawić limit czasu, każdy czas mniej:
function doTaskWithEnd($uri, $end, $ctx = null) {
if (!$ctx) { $ctx = stream_context_create(); }
stream_context_set_option($ctx, "http", "timeout", $end - time());
$ret = file_get_contents($uri, false, $ctx));
if ($ret === false) {
throw new \Exception("Request failed or timed out!");
}
return $ret;
}
$end = time() + 100;
$fetched = doTaskWithEnd("http://example.com/some/module/fetch", $end);
$ctx = stream_context_create(["http" => ["method" => "POST", "content" => $fetched]]);
$parsed = doTaskWithEnd("http://example.com/some/module/parsed", $end, $ctx);
$ctx = stream_context_create(["http" => ["method" => "PUT", "content" => $parsed]]);
doTaskWithEnd("http://example.com/some/module/save", $end, $ctx);
Lub alternatywnie z n na blokowaniu rozwiązanie (użyjmy amphp/AMP + amphp/ARTAX do tego):
function doTaskWithTimeout($requestPromise, $timeout) {
$ret = yield \Amp\first($requestPromise, $timeout);
if ($ret === null) {
throw new \Exception("Timed out!");
}
return $ret;
}
\Amp\execute(function() {
$end = new \Amp\Pause(100000); /* timeout in ms */
$client = new \Amp\Artax\Client;
$fetched = yield from doTaskWithTimeout($client->request("http://example.com/some/module/fetch"));
$req = (new \Amp\Artax\Request)
->setUri("http://example.com/some/module/parsed")
->setMethod("POST")
->setBody($fetched)
;
$parsed = yield from doTaskWithTimeout($client->request($req), $end);
$req = (new \Amp\Artax\Request)
->setUri("http://example.com/some/module/save")
->setMethod("PUT")
->setBody($parsed)
;
yield from doTaskWithTimeout($client->request($req), $end);
});
Teraz pytam, czy naprawdę chcą odciążyć odrębnych wniosków? Czy nie możemy po prostu założyć, że teraz są teraz funkcje?
W tym przypadku jest to łatwe i po prostu może skonfigurować alarm:
declare(ticks=10); // this declare() line must happen before the first include/require
pcntl_signal(\SIGALRM, function() {
throw new \Exception("Timed out!");
});
pcntl_alarm(100);
$fetched = fetch();
$parsed = parse($fetched);
save($parsed);
pcntl_alarm(0); // we're done, reset the alarm
Alternatywnie, roztwór non-blocking działa zbyt (zakładając fetch()
, parse($fetched)
i save($parsed)
prawidłowo powrócić Promises i mają zakaz blockingly):
\Amp\execute(function() {
$end = new \Amp\Pause(100000); /* timeout in ms */
$fetched = yield from doTaskWithTimeout(fetch(), $end);
$parsed = yield from doTaskWithTimeout(parse($fetched), $end);
yield from doTaskWithTimeout(save($parsed), $end);
});
Jeśli tylko chcą mieć globalny limit czasu dla różnych kolejnych zadań, bym najlepiej iść z robi to po prostu wszystko w o ne skrypt z numerem pcntl_alarm()
, alternatywnie można skorzystać z opcji limitu czasu dla strumienia.
Rozwiązania nieblokujące są stosowane głównie w przypadku konieczności wykonywania innych czynności w tym samym czasie. Na przykład. jeśli chcesz wykonać to pobranie + analizowanie + zapisywanie cyklu kilka razy, niezależnie od siebie.
Myślę, że to normalne i możesz to zrobić, ale dlaczego nie robisz tego na jednym php? Czy chcesz go używać z interfejsem API? Lub te adresy URL w swoim własnym projekcie? –
@TeymurMardaliyerLennon Nie chcę uruchamiać wszystkiego w tym samym czasie w przypadku przekroczenia limitu czasu. –
Do takich rzeczy jak uruchamianie pracowników w bogatych konfiguracjach używam RabbitMQ https://www.rabbitmq.com/tutorials/tutorial-two-php.html "Głównym założeniem kolejki pracy (vel: Queues zadań) jest unikaj natychmiastowego wykonania zadania wymagającego dużego nakładu pracy i poczekaj aż skończy się " –