php / php/php-src

FPM idle or req timeout causes no child available if write is delayed

Aperta
#11,765 1 commento 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Bug SAPI: fpm
Lingua principale
C
Stelle
40.4k
Fork
8.1k
Merge medio
2g 13h
PR unite (30g)
96

Descrizione

Description

This problem can happen in ondemand mode if the connection is established but there is a significant write delay and pm.process_idle_timeout is set even to shorter value. In such case process idle can remove all children. But probably because the connection is established, it is past creating new child so the request fails.

The following tests results in such issue:

--TEST--
FPM: Process manager config pm.process_idle_timeout with keep alive set
--SKIPIF--
<?php
include "skipif.inc";
if (!getenv("FPM_RUN_RESOURCE_HEAVY_TESTS")) die("skip resource heavy test");
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
?>
--FILE--
<?php

require_once "tester.inc";

$cfg = <<<EOT
[global]
error_log = {{FILE:LOG}}
log_level = debug
[unconfined]
listen = {{ADDR}}
pm = ondemand
pm.max_children = 3
pm.min_spare_servers = 1
pm.process_idle_timeout = 1
pm.status_path = /status
;request_terminate_timeout = 2
EOT;

$code = <<<EOT
<?php
usleep(300000);
EOT;

$tester = new FPM\Tester($cfg, $code, clientTransport: 'stream');
$tester->start();
$tester->expectLogStartNotices();
//$tester->multiRequest(2, connKeepAlive: true);
$tester->multiRequest(2, connKeepAlive: true, writeDelay: 3000, readTimeout: 5000);
$tester->status([
    'total processes' => 2,
]);
// wait for process idle timeout
sleep(2);
$tester->status([
    'total processes' => 2,
]);
$tester->terminate();
$tester->expectLogTerminatingNotices();
$tester->close();

?>
Done
--EXPECT--
Done
--CLEAN--
<?php
require_once "tester.inc";
FPM\Tester::clean();
?>

Resulted in this output:

PHP Notice:  fwrite(): Send of 611 bytes failed with errno=104 Connection reset by peer

But I expected this output instead:

no error
PHP Version

PHP 8

Operating System

Linux

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia con il reproducer incorporato di FPM\Tester, in particolare la configurazione ondemand, pm.process_idle_timeout, la connessione keep-alive e la scrittura ritardata. Esegui il test che usa molte risorse su Linux ed esamina la gestione dell’inattività dei processi di FPM e il relativo output del test; il lavoro è completato quando la richiesta ritardata rimane utilizzabile e non produce alcun avviso di reimpostazione della connessione.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
c, php
Ambito
backend, testing
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.