Daemonising to continue asynchronously

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Andy Jeffries

    Daemonising to continue asynchronously


    I've got a script which calls (via exec) "php myscript.php --params=here".

    Within myscript.php I try to become a daemon (to continue asynchronously
    from the calling script) using pcntl_fork, posix_setsid and pcntl_fork
    again.

    It works if I call the myscript.php from the command line (it correctly
    damonises and returns immediately, carrying on processing in the
    background), but when I do it through Apache (request the calling
    script) it waits for the child to complete first.

    Anything obvious I'm doing wrong?

    I'll happily post snippets of the script here, but I'd imagine it's
    something fundamental I'm missing.

    Cheers,


    Andy

    --
    Andy Jeffries MBCS CITP ZCE | gPHPEdit Lead Developer
    http://www.gphpedit.org | PHP editor for Gnome 2
    http://www.andyjeffries.co.uk | Personal site and photos

  • fletch

    #2
    Re: Daemonising to continue asynchronously

    Yup, children are killed when the server process dies. (try telling
    that to non programming folk.) I don't think that you can do this from
    a request. I would either set it up properly as a daemon if I have
    access to the boot proceedure, or get cron to start it, making sure the
    script dies if there is already one instance running.

    I could be wrong about this, but I have looked into it before.

    Comment

    • NC

      #3
      Re: Daemonising to continue asynchronously

      Andy Jeffries wrote:[color=blue]
      >
      > I've got a script which calls (via exec) "php myscript.php --params=here".[/color]

      Why not use "php myscript.php --params=here &"?

      Cheers,
      NC

      Comment

      • Andy Jeffries

        #4
        Re: Daemonising to continue asynchronously

        On Mon, 24 Apr 2006 09:50:59 -0700, NC wrote:[color=blue][color=green]
        >> I've got a script which calls (via exec) "php myscript.php
        >> --params=here".[/color]
        >
        > Why not use "php myscript.php --params=here &"?[/color]

        Because it still seems to wait on the script finishing before continuing.

        Cheers,


        Andy

        --
        Andy Jeffries MBCS CITP ZCE | gPHPEdit Lead Developer
        http://www.gphpedit.org | PHP editor for Gnome 2
        http://www.andyjeffries.co.uk | Personal site and photos

        Comment

        • Andy Jeffries

          #5
          Re: Daemonising to continue asynchronously

          On Mon, 24 Apr 2006 09:45:18 -0700, fletch wrote:[color=blue]
          > Yup, children are killed when the server process dies. (try telling that
          > to non programming folk.)[/color]

          That and reaping zombies :-)

          (and I always prefer to term is as children are killed when the parent
          process dies - sounds more sinister :-))
          [color=blue]
          > I don't think that you can do this from a
          > request. I would either set it up properly as a daemon if I have access to
          > the boot proceedure, or get cron to start it, making sure the script dies
          > if there is already one instance running.
          >
          > I could be wrong about this, but I have looked into it before.[/color]

          It's very odd. Daemonising from the command line works fine, it's just
          when it's run from within an Apache request...

          I may well have to do it by creating a full daemon process that is xinetd
          monitored and just send requests through a socket. More hassle than I
          wanted...

          Cheers,


          Andy


          --
          Andy Jeffries MBCS CITP ZCE | gPHPEdit Lead Developer
          http://www.gphpedit.org | PHP editor for Gnome 2
          http://www.andyjeffries.co.uk | Personal site and photos

          Comment

          • Andy Jeffries

            #6
            Re: Daemonising to continue asynchronously

            On Mon, 24 Apr 2006 14:50:24 +0000, Andy Jeffries wrote:[color=blue]
            > I've got a script which calls (via exec) "php myscript.php --params=here".
            >
            > Within myscript.php I try to become a daemon (to continue asynchronously
            > from the calling script) using pcntl_fork, posix_setsid and pcntl_fork
            > again.
            >
            > It works if I call the myscript.php from the command line (it correctly
            > damonises and returns immediately, carrying on processing in the
            > background), but when I do it through Apache (request the calling
            > script) it waits for the child to complete first.[/color]

            OK, I found out the problem. My "become daemon" function didn't close
            stdout, so Apache always waited on stdout EOFing even though the process
            went in to the background.

            Fixed now.

            For anyone interested, a working function to become a Daemon (background
            task, unattached from the parent process) from a PHP CLI script is:

            function become_daemon()
            {
            $pid = pcntl_fork();
            if ($pid == 1) {
            die("Could not fork");
            }
            else if ($pid) {
            exit; // Parent process should exit nicely
            }

            $detach = posix_setsid();
            if (!$detach) {
            die("Could not detach");
            }

            if (pcntl_fork())
            exit;

            $stdout = fopen("php://stdout", "w");
            fclose($stdout) ;
            // Now we're a daemon
            }

            Cheers,


            Andy


            --
            Andy Jeffries MBCS CITP ZCE | gPHPEdit Lead Developer
            http://www.gphpedit.org | PHP editor for Gnome 2
            http://www.andyjeffries.co.uk | Personal site and photos

            Comment

            • Andy Jeffries

              #7
              Re: Daemonising to continue asynchronously

              On Mon, 24 Apr 2006 09:45:18 -0700, fletch wrote:[color=blue]
              > Yup, children are killed when the server process dies. (try telling that
              > to non programming folk.) I don't think that you can do this from a
              > request. I would either set it up properly as a daemon if I have access to
              > the boot proceedure, or get cron to start it, making sure the script dies
              > if there is already one instance running.
              >
              > I could be wrong about this, but I have looked into it before.[/color]

              Found the problem, see my reply to my post. The become_daemon function
              was working fine, but it still held the file handle to stdout open (as
              child processes inherit open file handles) and therefore PHP waited for an
              EOF on the stdout handle from the child.

              Closing stdout (along with the previously described pcntl_fork,
              posix_setsid, pcntl_form) works a charm.

              Cheers,


              Andy

              --
              Andy Jeffries MBCS CITP ZCE | gPHPEdit Lead Developer
              http://www.gphpedit.org | PHP editor for Gnome 2
              http://www.andyjeffries.co.uk | Personal site and photos

              Comment

              • fletch

                #8
                Re: Daemonising to continue asynchronously

                > For anyone interested, a working function to become a Daemon (background[color=blue]
                > task, unattached from the parent process) from a PHP CLI script is:[/color]

                <sinp code>

                this is useful code but I would like to point out that a daemon should
                automatically restart when it dies unexpectedly, and ensure that only
                one instance is running, not covering these cases is usally a bad
                thing. It depends what the daemon does of course.

                Comment

                • Andy Jeffries

                  #9
                  Re: Daemonising to continue asynchronously

                  On Mon, 24 Apr 2006 14:45:34 -0700, fletch wrote:[color=blue][color=green]
                  >> For anyone interested, a working function to become a Daemon (background
                  >> task, unattached from the parent process) from a PHP CLI script is:[/color]
                  >
                  > <sinp code>
                  >
                  > this is useful code but I would like to point out that a daemon should
                  > automatically restart when it dies unexpectedly, and ensure that only one
                  > instance is running, not covering these cases is usally a bad thing. It
                  > depends what the daemon does of course.[/color]

                  Absolutely, daemon probably isn't the right word, fully detached process
                  would probably be better.

                  Although Apache is a daemon, but if the main apache process dies then it
                  won't automatically restart by itself will it (it relies on
                  start-stop-daemon or the like).

                  Anyway, thought the code may help someone in the future.

                  Cheers,


                  Andy

                  --
                  Andy Jeffries MBCS CITP ZCE | gPHPEdit Lead Developer
                  http://www.gphpedit.org | PHP editor for Gnome 2
                  http://www.andyjeffries.co.uk | Personal site and photos

                  Comment

                  Working...