James Berry <jberry@macports.org> writes:
Hi all, and sorry I haven't chimed in on this thread earlier. I'll answer a few questions below...
On Sep 4, 2007, at 1:47 PM, markd@macports.org wrote:
Blair Zajac <blair@orcaware.com> writes:
Looks good Mark.
It doesn't explain why one would use launchd or daemondo. Is this the appropriate place to put it, or is it described elsewhere?
Hi Blair,
Yes you're right it doesn't say, and this would be the appropriate place. Fact is, I'm not sure the answer. James' original notes said that startupitem.executable was the preferred type, but it didn't say why. If daemondo doesn't monitor and restart daemons, as I guess it can't since it only knows about scripts, then perhaps that is the reason.
daemondo will indeed quit when it detects that the launched process has quit, and thus will "keep alive" the process, since launchd will then restart daemondo. In this way, daemondo acts as a shim or adapter between the scripts supported by the startupitem command, and the single process expected by launchd.
The reason that startupitem.executable is preferred is that this gives the best possible chance that daemondo will be able to detect the death of the launched process: since daemondo can launch the process, it can also detect when it quits, stop it, etc.
For those cases where startupitem.executable cannot be used, daemondo also supports the startupitem.pidfile commands that allow the process' pidfile to be monitored: daemondo will read the pidfile and watch for the death of that process.
So daemondo, and thus launchd, will be aware of the daemon process death (and be able to restart the daemon process) only under two circumstances:
(1) startupitem.executable was supplied (thus daemondo starts the process) (2) startupitem.pidfile was supplied (thus daemondo reads the process id)
Under all other circumstances, daemondo will not know that the daemon process has died, and will not exit when the process does die, and thus launchd won't restart the process since it doesn't know it died. Put another way, if daemondo can know the process has died, then launchd will know too, but not otherwise.
But since so many apps just have startup scripts that don't monitor and restart their daemons, it seems odd to call it the "preferred type" since if that is to be done whenever possible (even when developers provide startup scripts), we'd be establishing a higher standard with ports than the developers who created the programs consider necessary. So I wonder if the "why" question doesn't come down to:
1) If a port author wants the daemon monitored and restarted if it dies, use an executable startupitem type.
Note that for simplicity, startupitem.executable is handled by daemondo at present. This has two purposes:
- It keeps the startupitem generating code a little simpler. - It allows the potential support for higher value services to be provided by daemondo. In particular, note daemondo's --restart- netchange option, which can be quite useful, but for which there is no current support by the startupitem keys.
2) Otherwise, use a wrapper type (daemondo) startup script if the developer provided a startup script that works ok on the target platform and the deamon isn't unstable for some reason.
In most cases, the second step after using startupitem.executable should be to make sure that the pidfile is identified (if there is one) since this will allow daemondo to track the process and will lead in most cases to satisfaction.
3) If the developer didn't provide a startup script or one that works ok on the target platform, you may use either executable or wrapper startupitem types. Unless we can establish executable startupitems are *really* the preferred type for MacPorts, then the advice is: executable if possilble and wrapper if not.
Yes, executable really are the preferred means, with pidfile close behind.
If I can arrive at some answers on this I can clarify that section.
Also, for startupitem.pidfile, the default is shown as
Default: none | ${prefix}/var/run/${name}.pid
is one for launchd and the other for daemondo?
No and I struggled on that one because the startupitem.pidfile keyword has two separate values: one specifies the pid handling behavior, the other the pidfile path. So there are two defaults for the one keyword. Also, since the keyword is of a type "executable", it cannot be used with wrapper startupitems.
Hi James, Thanks for the info. The startupitem behavior is not as I thought so I'll have to rework the guide section after reading your email carefully later tonight. But some initial questions:
Note that for simplicity, startupitem.executable is handled by daemondo at present. This has two purposes:
I didn't know that.
Also, since the keyword is of a type "executable", it cannot be used with wrapper startupitems.
Hmm. I don't get your distinction between these "types". The pidfile keyword is likely used only if executable is not.
I understand by your response that the startupitem.pidfile may be used without startupitem.executable, and with it as well. So I categorized the startupitem.pidfile wrong. But there needs to be some distinctions made in startupitem types. If the startupitem.executable is preferred; what are the alternative types over which it is preferred? There are 10 other startupitems keywords, so are there 9 other types? Obviously not. And the manpage says: "This (executable) is the preferred type of startup item rather than any of startupitem.init, startupitem.start, startupitem.stop, or startupitem.restart, and may not be used together with any of these options." To what type does this other collection of startupitems belong? "Non-executable", "wrapper", or some such name needs to be established for that type. So I see 3 categories of startupitems keywords: A) executable (only one of them), B) "non-executable" or "wrapper" or some other name, C) naming and logging (startupitems that don't have to do with a type). Type A and B can't be mixed together, and type C are attributes that may be used with either A or B. Maybe it could be classified better, but I think we really need some coherent way of categorizing these items and relating them to each other. Mark