Upstart 1.0 Design discussion
Casey Dahlin
cdahlin at redhat.com
Wed Sep 16 01:18:56 BST 2009
On 09/14/2009 09:21 AM, Scott James Remnant wrote:
>> I'll save my follow-up for LPC. It may take some intense explanation.
>> The crux of it is that we might be able to implement a few more stanzas
>> that don't outwardly make sense, and, with the addition of being able to
>> #include other files within job definitions, be able to eliminate large
>> quantities of upstart's code in favor of a job state machine described
>> in job definition syntax. Freaky huh?
>>
> I think it's a good idea to write things down on the mailing list,
> rather than save them for LPC - even if the in-person stuff goes
> different directions, it means those on the ML get a preview of what
> you're thinking of ;-)
>
> (Also the very process of writing a mail tends to help focus the
> thoughts)
>
> Scott
>
Well, since you say so, and since I promised a brain-dump today...
Lets suppose an extremely simplified version of upstart. It has "Jobs"
as you describe them, but jobs are either "up" or "down," that is they
don't have these starting/started/stopping/stopped events/states.
They do have while stanzas, which relate them to other jobs, and on
stanzas which let them react to events. They emit two events, one when
they come up, and one when they go down.
Lets also, for a moment, rip out all the service management. For the
moment, Jobs aren't jobs. They just hold a condition, and that's it.
Forget for just a second about interacting with processes.
Now, lets add a series of seemingly useless features, and then I'll
perform a magic trick with them.
First we'll add the implements stanza: lets require every job to have a
stanza called implements. It looks like this:
implements service
Every job must have one, and only one. The majority of them will have
"service" as the argument. What does this do? It looks for a file in
/etc/init/types/ called service.conf, and bodily includes it at the top
of our job definition file. Inside of the included file, it expands the
string @job to be the name of the job it was included in. Weird? Yes.
I'm going to set this aside and come back to it later, but let me point
out one thing: this stanza, whatever its use, would be reeeeeely easy to
implement. Dirt cheap.
Lets add another, stranger one. "job." It looks like this:
job foo
on bar
when baz
end job
This lets us create other jobs inside of a job definition. The new job
is a "sub-job" of the job we define. So, for example: If in a file
"boing.conf" we had the above stanza, there would be a new job called
"boing foo". Note that this doesn't adjust the state of the job at all:
"boing" can be down, and "foo" can be up. Also notice we use whitespace
as a namespace separator, rather than "boing.foo" or "boing:foo".
Its weird, but again, reeeeeely easy and cheap to implement.
Lets try one more:
somename exec /bin/action
some_othername script
/bin/action
end script
These are action definitions. They associate a script with a variable in
the job (called somename, or some_othername in this case). We can make
them start like this:
spawn somename on fooevent
kill somename TERM on fooevent
Spawn simply executes the script stored at "somename" and leaves. It
doesn't monitor it or tie it to the job in anyway. However, events will
be emitted while somename is running at interesting times (forking,
dieing, etc). Matching one would look like this:
on foojob somename SIGTERM
Kill does what you'd expect. It sends a signal to the process if running.
One more caveat, if you omit the name, a name of _default is assumed, so
_default exec /bin/action
does the same thing as
exec /bin/action
Its an odd, gutted sort of return of the service management
functionality, but it comes without any internal state machines, just
trivial notifications, which are not obviously useful, but, again,
reeeeely cheap to implement.
So the magic trick: remember that service.conf file? Lets put some stuff
in it.
Hey y'all, watch this:
spawn _default on @job starting
kill _default TERM on @job stopping
job starting
from @job up until (@job running up or @job stopping up or
@job down)
on @job up or @stopping down
end job
job running
from @job _default forked until (@job stopping or
@job _default exited)
end job
job stopping
from @job up until @job starting
on @job running down
end job
So we cut out most of upstart, added 3 things that are all reeeeeeely
cheap to implement, and got most of what we cut out back. Perfect? Not
yet, but interesting...
--CJD
More information about the upstart-devel
mailing list