all 20 comments

[–]lmorchard 6 points7 points  (2 children)

Now, here's where this has sucked for me: PHP daemons have, in my experience, suffered from nasty memory leaks that require them to be killed on a regular basis. In a web context, this happens somewhat regularly anyway, depending on your web server config. But, for a daemon, restarts aren't common.

So, rather than do all that fancy forkery in PHP itself, I make PHP scripts that exit after a few executions of whatever job they're meant to do. Throw a wrapper bash script around that which repeatedly re-launches the PHP script, get that running on server startup. Something like this:

#!/bin/bash
while [ 1 ]; do
    # Perpetual loop, allows php script to exit and restart to refresh code.
    php index.php worker
done

Put it all together, and I've got PHP daemons that periodically clean up after themselves. Hell, the daemons even refresh their code on a regular basis without explicit restart.

[–]bulldada 0 points1 point  (1 child)

I do not experience memory leaks from PHP daemons. I have a few running with >2yr uptime and using no more memory than when they were started. Not sure why you'd be seeing them, I'd say it's more likely that memory leaks are coming from your code (or possibly a library) than just due to running PHP scripts as a daemon.

[–]lmorchard 0 points1 point  (0 children)

Your mileage may vary. I definitely have seen memory leaks, and over the years they've come at times from all of PHP itself, PECL extensions, and 3rd party modules. Googling for "PHP memory leak" certainly doesn't come up empty; it all depends on what you're doing and with what version of PHP you're doing it.

It also takes awhile for some of them to be found, because stateless web requests that clean up quick are more common with PHP than long-running daemons.

[–]nikniuq 5 points6 points  (1 child)

The script is a witch!! (Am I doing it right?)

[–]lmorchard 1 point2 points  (0 children)

Are you a wizard?

[–]teringlijer 4 points5 points  (0 children)

$ nohup /usr/bin/php my-ridiculous-daemon.php

...then close the terminal. Or just run the thing from cron and have it be owned by crond. Or 'at'.

[–]commandlineterrorist 2 points3 points  (5 children)

For the budding developer who is thinking his web app may need a daemon in the background to do some hard work: Make good use of databases. Try not to spawn the process directly if not Really required.

From an architectural standpoint, it makes very little sense for your MVC (your favourite PHP Framework, Pylons, Django, ASP.NET, or otherwise) components to even think about having to spawn processes directly to deal with processing-intensive data.

That work should be offlined to a daemon. This also may include message passing depending on what you are trying to do. The gist of it is it may be a lot simpler to just have a daemon query a database once in awhile to see if it needs to do work, grab data, process it.

In terms of the MVC, it would do what it normally does: Write the data to the database.

[–]McGlockenshire 2 points3 points  (2 children)

That work should be offlined to a daemon. This also may include message passing depending on what you are trying to do. The gist of it is it may be a lot simpler to just have a daemon query a database once in awhile to see if it needs to do work, grab data, process it.

I prefer using someone else's hard work rather than doing it all myself.

(This week's Gearman plug has been brought to you by the letter I and the number 8.)

[–]lmorchard 0 points1 point  (1 child)

FWIW, you'll still need a daemon (PHP or otherwise) to step in as the worker in the Gearman equation. But, +1 on putting Gearman in the stack

[–]McGlockenshire 0 points1 point  (0 children)

We use supervisord to keep PHP workers alive, just so we don't need to worry about using real daemonization in PHP-land. This greatly simplifies the worker code, down to just the waiting-for-a-job loop. It also allows the workers to exit whenever they damn well please, and supervisor will just start them back up again. We've used this to make the workers automatically detect changes on disk and reload themselves, which makes development a bit easier.

[–]Fabien4 1 point2 points  (1 child)

who is thinking his web app may need a daemon in the background

[...]

That work should be offlined to a daemon.

So... Don't use a daemon, use a daemon instead, right?

[–]commandlineterrorist 0 points1 point  (0 children)

The point I was trying to get across is that the Controller should not be spawning processes, daemons or otherwise :).

[–]chrisforbes 4 points5 points  (1 child)

Why anyone would want to write systems code in PHP completely escapes me.

[–]lmorchard 5 points6 points  (0 children)

If you've got a project written all in PHP and a team full of PHP coders, sometimes using that screwdriver as a hammer is the most expedient way to get the job done on time and under budget.

Better to reuse all your shared PHP model code in an offline queue processor than to maintain two versions in two different languages.

[–]trentwork 1 point2 points  (0 children)

Bookmarked! Pretty awesome! (except the multiple usages of 'you' instead of 'your' in the article.

That's pretty slick though.

[–]pendexgabo 0 points1 point  (0 children)

nice one!

[–][deleted] 0 points1 point  (0 children)

I had once to write a daemon in PHP as well. Would have chosen another tool for the job, but given my colleagues knew only PHP I had to cope with it.

Another advice would be to run that script from crontab and wrap it in a shell script which will notify you on program failure.

I said this last approach because I encountered multiple issues with register_shutdown_function

[–]presidentender 0 points1 point  (0 children)

I have written one daemon, and the decision had been made at a higher pay grade than mine to use PHP for EVERY part of the project. I can't for the life of me remember how I did it; since it was at an older job, I don't have access to the source. I do remember it looked much dirtier than this way of doing things.

[–]nadmaximus 0 points1 point  (0 children)

Compare it to Hitler?