Processo filho assíncrono no script FastCGI

Processo filho assíncrono no script FastCGI

Suponha que eu queira que meu servidor durma em qualquer solicitação HTTP para o caminho /sleep(ou seja http://hostname/sleep), mas também envie uma resposta completa ( HTTP 200) antes de dormir.

UsandonginxcomFastCGI, eu configurei o caminho nonginxconfiguração:

location /sleep {
    fastcgi_pass unix:/path/to/fcgiwrap.socket;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME /path/to/script.sh;
}

Isso invoca o seguinte script ( /path/to/script.sh):

#!/bin/sh
# -*- coding: utf-8 -*-
cat << EOF
Content-Type: text/html

<html><head><title>Sleep</title><meta charset="UTF-8"></head>
<body><p>Sleep: $(date)</p></body></html>
EOF
sleep 1 && sudo systemctl suspend < /dev/null > /dev/null 2>&1 &

Mesmo que isso suspenda o sistema,FastCGIserá bloqueado até que o processo filho seja concluído, o que significa que a solicitação da web não será concluída antes que o sistema entre em suspensão. Então, como faço para separar esse comando final da supervisão porFastCGIpara que a resposta seja concluída, mas o comando continue em segundo plano, neste caso, em última análise, para suspender o sistema?

Responder1

Você pode dissociar o cgi e a suspensão interpondo um arquivo usado como gatilho do systemd. Consulte man systemd.pathpara esta ativação baseada em caminho de uma unidade. Tem a vantagem de não precisar usar o sudo do cgi.

Crie um arquivo de unidade/etc/systemd/system/mycgitrigger.path

[Path]
PathModified=/some/writeable/file
[Install]
WantedBy=multi-user.target

e habilite-o. Altere o script cgi para simplesmente escrever qualquer coisa no arquivo /some/writeable/filepara acionar o desligamento. Coloque o comando short timeout e shutdown em um arquivo de unidade /etc/systemd/system/mycgitrigger.service(que não precisa ser habilitado).

Responder2

A solução óbvia seria

echo "sleep 1 && sudo systemctl suspend" | at now

informação relacionada