0

I need to run code in background for some time, after output is send to client.
But connection blocks and won't close until job is finished.

Looked at :
 How do I close a connection early?
 https://www.php.net/manual/en/features.connection-handling.php#71172
(and other linked answers)

I ended up with code :

    // credit : https://stackoverflow.com/questions/138374/how-do-i-close-a-connection-early#141026
    //          and related sources
    // broken on : lighttpd/1.4.53 - php/7.1.3

    $size=ob_get_length();
    header("Content-Length: $size",1);
    header("Connection: close",1);
    header("Content-Encoding: none\r\n");

    // flush all output
    ob_end_flush();
    ob_flush();
    flush();
    ob_end_clean();

    // if you're using sessions, this prevents subsequent requests
    // from hanging while the background process executes
    if (session_id()) session_write_close();

    ... some code for 10 seconds here

I tried both :
    server.max-keep-alive-idle=0
    server.max-keep-alive-requests = 0
Taken from :
    lighttpd force close connection
    https://serverfault.com/questions/283377/force-connection-close-lighttpd
(put inside /etc/lighttpd/lighttpd.conf)

My setup :
    lighttpd/1.4.53
    php/7.1.3
    Firefox 68.6.0esr (32-bit)
    Raspberry Pi 4
    Raspbian
    uname -a : Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux

Enabled lighttpd modules :
    10-accesslog.conf
    10-fastcgi.conf
    10-rewrite.conf
    15-fastcgi-php.conf
    90-javascript-alias.conf

Purpose :
 It's simple MUD game code.
 It is there to refresh AIs once per second.
 It is periodicaly started by player's presence in game like this :
 
 1] Script will process player's command,
    then connection should be closed to not bother player's browser
 2] check lock-file and if it's free - lock it
 3] then stay in background for 10 updates
    After that, file is unlocked,
    so another player's command can start another bg job

Jirka Justra
  • 187
  • 1
  • 7
  • could you be more detailed about what you're trying to accomplish by displaying more of your code? What is executing this code? – Nibb Apr 02 '20 at 14:34
  • 1
    @Nibb sure .. I isolated functional example here : https://pastebin.com/WBTDKVVC – Jirka Justra Apr 03 '20 at 02:26
  • 1
    @Nibb .. sorry, I now realized, that my question was really not well stated ... added 'purpose' at and of question – Jirka Justra Apr 03 '20 at 22:33

1 Answers1

0

If your code needs to do processing after it has sent a CGI response, then your code needs to do so in a separate execution context, since the CGI has done its job when it sends the CGI response, and lighttpd will then send a SIGTERM signal to your script.

One way to run code after sending a CGI response is to run the code in the background after sending a CGI response. See https://www.php.net/manual/en/function.posix-setsid.php

Another way is for your CGI to put a job into a job queue and have a standalone daemon, separate from the CGI, process the queue, e.g. using a redis server.

gstrauss
  • 2,091
  • 1
  • 12
  • 16
  • It is meant to be run on server without such level of control (payed hosting), so I came up with this self-started background thingy .. I forgot to mention it, sorry – Jirka Justra Apr 03 '20 at 22:54