[11:17] <AlexExtreme> strange
[11:17] <AlexExtreme> is it normal that my karma in launchpad goes up without me doing anything?
[11:19] <Kamping_Kaiser> yeh, LP is whacko
[11:19] <AlexExtreme> heh
[11:28] <Keybuk> heh
[11:34] <_ion> It would be easy to make a script that creates a graphviz graph alike the one in the wiki of the current system, btw. It would just need a purely informational stanza about events a job may emit, e.g. fhs_check could contain 'emits fhs-filesystem-mounted fhs-filesystem-unmounted'.
[11:35] <Keybuk> yeah
[11:36] <_ion> I'll probably write that script later.
[11:36] <Kamping_Kaiser> didnt notice you here Keybuk 
[11:38] <Keybuk> ... I have always been here ...
[11:38] <Kamping_Kaiser> ... oh ...
[11:38] <_ion> after the complex-event-config spec is final.
[11:41] <Keybuk> Kamping_Kaiser: actually, that's a lie, I can't back that up
[11:52] <Keybuk> _ion: http://upstart.ubuntu.com/wiki/Emits
[12:02] <_ion> keybuk: Nice, thanks.
[12:14] <_ion> keybuk: Hm, will all that information (the "start/stop on" and the "emits" events) about current jobs be exposed via libupstart? I could just write the bindings for libupstart and use them.
[12:15] <Keybuk> I think so
[12:15] <Keybuk> not sure which works best
[12:15] <Keybuk> have a tool ask upstart for job relationships
[12:15] <Keybuk> or parse the configuration files itself
[12:18] <_ion> Yeah, that's what i'm pondering. :-)
[12:18] <Keybuk> I think the former, that way what you see is always consistent with what upstart knows
[12:18] <Keybuk> and allows for future registry of jobs from other sources (e.g. autostart files)
[12:18] <_ion> Yeah.
[03:09] <wasabi> morning folks
[03:09] <Keybuk> heyhey
[03:10] <wasabi> where did we leave off yesterday?
[03:10] <wasabi> Oh yes! Yeah. You have a real job. It just seems like it's too good to be real. ;)
[03:10] <Keybuk> it has its downsides, like any other
[03:14] <Keybuk> I'm just going through the specs tidying them up and marking those we're pretty much agreed on as approved
[03:24] <Keybuk> well, that was a conversation killer :p
[03:31] <wasabi> Heh.
[03:37] <Keybuk> so, I was thinking on last night's conversation
[03:37] <Keybuk> I'm convinced that the eight-stage state machine is correct, though the names could do with a little tweaking
[03:38] <Keybuk> however I think I agree that there should not be eight corresponding events
[03:38] <Keybuk> the main reason being that the paths through the state machine aren't circular
[03:38] <Keybuk> e.g. you could have a start event, but a failure along the way, which could cause you to go straight to stopped
[03:38] <Keybuk> so anything with "from start FOO to stop FOO" wouldn't actually get stopped
[03:39] <Keybuk> and I think that inconsistency is bad
[03:39] <Keybuk> going through all the examples, I couldn't find anything that really needed that level of complexity
[03:39] <Keybuk> so I propose keeping the state machine *but* reducing the events
[03:39] <Keybuk> in fact, there should be just two pairs
[03:39] <Keybuk> "start"/"starting" = goal changed to start, process begun
[03:40] <Keybuk> "stop/stopping" = goal changed to stop, process begun
[03:40] <Keybuk> "started" = process of starting finished
[03:40] <Keybuk> "stopped" = process of stopping finished
[03:40] <Keybuk> these events would be emitted at the most appropriate places in the state machine
[03:40] <wasabi> I agree wholeheartedly.
[03:40] <Keybuk> and would always go
[03:40] <Keybuk> starting -> started
[03:40] <Keybuk> or
[03:40] <Keybuk> starting -> stopping -> stopped
[03:40] <Keybuk> or stopping -> stopped
[03:40] <Keybuk> or stopping -> starting
[03:40] <Keybuk> etc.
[03:40] <Keybuk> so they make logical sense
[03:40] <wasabi> Yes.
[03:41] <Keybuk> if you get a starting event, you ALWAYS get at least stopping
[03:41] <wasabi> Makes sense.
[03:41] <Keybuk> and if you get a stopping event, you ALWAYS get at least starting following
[03:41] <wasabi> So, if pre-stop fails, it'll emit starting again?
[03:42] <Keybuk> right
[03:42] <Keybuk> goal changes back
[03:42] <wasabi> But not actually traverse through pre-start and post-start.
[03:42] <Keybuk> yup
[03:42] <wasabi> Super.
[03:42] <Keybuk> this also gives us an interesting idea
[03:42] <Keybuk> the started/stopped events are just "now at rest" events
[03:42] <wasabi> Yup.
[03:42] <Keybuk> but the starting/stopping events are "goal being changed"
[03:43] <Keybuk> we could delay any action on those two events until they've been hancled
[03:43] <Keybuk> uh, handled
[03:43] <Keybuk> so:
[03:43] <Keybuk> start ssh => sets goal to start => emits "starting ssh" => waits for event to finish => changes state to pre-start
[03:43] <Keybuk> likewise for stopping
[03:44] <Keybuk> stop ssh => sets goal to stop => emits "stopping ssh" => waits for event to finish => changes state to pre-stop
[03:44] <Keybuk> so for the more usual example:
[03:44] <Keybuk> tomcat could be started on starting apache; which means that apache won't be started until apache is actually running
[03:44] <Keybuk> uh tomcat is actually running
[03:45] <wasabi> Yes. That makes sense for apache/tomcat.
[03:45] <Keybuk> network-manager could be stopped on stopping dbus; which means that dbus won't be stopped until network-manager has been stopped
[03:45] <wasabi> And that also makes perfect sense.
[03:45] <Keybuk> are there any examples of something you would run "on starting" or "on stopping" which _shouldn't_ delay the named job?
[03:45] <wasabi> And in both cases the definition of the dependency is described from the POV of the depending service.
[03:45] <wasabi> Say that again?
[03:46] <wasabi> Ahh I see.
[03:46] <wasabi> I'm unsure.
[03:47] <wasabi> I can't see it.
[03:47] <wasabi> I think the most likely case is desiring a service to run on started.
[03:48] <wasabi> Which leaves the emitting job at rest, done, so blocking doesn't matter.
[03:49] <wasabi> And I can't imagine any circumstances where that isn't good enough.
[03:49] <_ion> I agree with having only starting/stopping/started/stopped emitted.
[03:50] <_ion> And with "on starting" and "on stopping" causing the emitting job to wait.
[03:51] <wasabi> I think the only desire to have something start but not block "starting" is simply because it's reactionary, but independent. It doesn't actually care about the state of the first job.
[03:51] <wasabi> Thus making it more async.
[03:52] <wasabi> And I would probably say that that could be handled better. Don't make your job block.
[03:52] <wasabi> Let it start quick.
[03:52] <_ion> Can you think of an use case for having "on starting" without blocking?
[03:52] <Keybuk> how would you define that, though?
[03:52] <wasabi> Define it? By geting through pre-start FAST.
[03:53] <Keybuk> *confused*
[03:53] <wasabi> Don't just spin in pre-start.
[03:53] <wasabi> Well, the blocking is only waiting for the dependent job to be started
[03:53] <Keybuk> the only use cases I can think of for "on starting" do suggest blocking
[03:53] <wasabi> Which is waiting from child stopped->started
[03:53] <Keybuk> yeah
[03:54] <wasabi> I can't imagine that being slow enough to be unsatisfactory justify 
[03:54] <wasabi> s/justify//
[03:59] <wasabi> I guess the only potential bottleneck I can think of is that if somebody wants to have their job run before apache runs, but their job is waiting on some other external resource before it starts.
[03:59] <wasabi> And they represent that waiting by spinning in pre-start =)
[03:59] <Keybuk> I'd argue that's a bug anyway :)
[03:59] <wasabi> And that seems pretty broken anyways.
[03:59] <wasabi> Yeah
[04:02] <wasabi> running to work now
[04:03] <wasabi> Are we suseptable to any sort of feedback loop with this?
[04:03] <wasabi> Or deadlocking
[04:04] <Keybuk> you can be deadlocked by two jobs
[04:04] <Keybuk> foo:  start on starting bar
[04:04] <_ion> A "start on starting B" and B "start on starting A"?
[04:04] <Keybuk> bar:  start on starting foo
[04:05] <Keybuk> actually, no you wouldn't
[04:05] <_ion> That could be easily detected, couldn't it?
[04:05] <Keybuk> because the "starting bar" event wouldn't affect foo, because it's goal is already set
[04:05] <Keybuk> bar would start immediately
[04:05] <Keybuk> and thus foo would too
[04:06] <_ion> Ah, nice.
[04:47] <Keybuk> hmm
[04:47] <Keybuk> what to do about respawn?
[04:47] <Keybuk> would you want an event for that?
[04:48] <Keybuk> should it be when it notices the job has died, or when it has successfully restarted it?
[04:53] <wasabi_> back
[04:53] <_ion> died foo 42   exit value
[04:53] <_ion> stopped foo
[04:53] <_ion> starting foo
[04:53] <_ion> started foo
[04:53] <_ion> ?
[04:53] <wasabi_> Nice.
[04:54] <wasabi_> I don't think an event is required for respawn specifically as much as "died"
[04:54] <wasabi_> And I *love* the idea of including the exit code in the event args
[04:54] <wasabi_> That's slick.
[04:54] <Keybuk> failed?
[04:54] <Keybuk> we have that already
[04:54] <wasabi_> Yeah.
[04:54] <Keybuk> my only concern there is that it'd cause any service using starting or stopping to get restarted
[04:54] <wasabi_> "jobname failed 1"
[04:54] <Keybuk> but maybe that's right too
[04:55] <wasabi_> Hmm.
[04:55] <Keybuk> actually, it'd only do it for anything on stopping
[04:55] <Keybuk> so if dbus died, all the dbus services would get restarted
[04:55] <wasabi_> That is most certainly appropiate.
[04:55] <wasabi_> At least in that case.
[04:56] <Keybuk> I suspect if something really needs to be stopped on stopping, and block the parent, that does imply that the connection is critical
[04:56] <wasabi_> I think failed is definatly a bug, as in, something which should never happen. But when it does, it's best to be conservative.
[04:56] <Keybuk> so does imply that respawning one means to respawn the other
[04:56] <wasabi_> When it fails, run the post-stop scripts, which would clean up on service stop.
[04:56] <wasabi_> Then cycle back through to start.
[04:57] <wasabi_> Also, the post-stop script, and in fact the pre-start script will have access to the event that caused it. Including args.
[04:57] <wasabi_> [ "$1" == "failed" ]  
[04:57] <Keybuk> yeah
[04:58] <Keybuk> ok, so another topic
[04:58] <wasabi_> There are cases where we have known buggy software, that people want to run, but we know is going to crash.
[04:58] <wasabi_> (nscd)
[04:58] <Keybuk> (from the same spec)
[04:58] <_ion> Hmm, if foo: "start on stopping bar" and bar fails, foo should be stopped. Should there be some magic, or should there be a dummy "stopping bar" event right after the "failed bar" event?
[04:59] <wasabi_> I think I lean towards having a dummy event.
[04:59] <_ion> Me too.
[04:59] <wasabi_> You know, we might not even have a failed event.
[05:00] <_ion> Whoops, i meant foo: "stop on stopping bar"
[05:00] <wasabi_> Are we going to use job names as events or start/stop ?
[05:00] <wasabi_> We should decide that once and for all. ;)
[05:00] <Keybuk> wasabi: right, so let's discuss that now
[05:01] <Keybuk> there's a good reason (imo) to make events have a _different_ namespace to jobs
[05:01] <Keybuk> the example event is the block-device-added event
[05:01] <Keybuk> we can write things like /etc/event.d/mount-filesystem with "on block-device-added"
[05:01] <Keybuk> but someone is going to try and write /etc/event.d/block-device-added
[05:01] <Keybuk> this has several effects
[05:01] <wasabi_> Hmm.
[05:02] <Keybuk> 1) it doesn't get triggered, whey they probably expect it to -- no matter, they can add "on block-device-added" in it
[05:02] <wasabi_> Weird events being mixed.
[05:02] <Keybuk> 2) so the block-device-added hda event from udev now starts the block-device-added job
[05:02] <wasabi_> You'd get block-device-added events with data that was not in fact a block device name
[05:02] <Keybuk> 3) which emits the block-device-added starting event
[05:02] <Keybuk> and poor mount-filesystem would get both
[05:02] <wasabi_> You win. =)
[05:02] <Keybuk> this is a real world problem
[05:03] <Keybuk> someone (me) shipped /etc/event.d/control-alt-delete in Ubuntu <g>
[05:03] <wasabi_> Heh.
[05:03] <Keybuk> which is why the event got renamed
[05:03] <Keybuk> so I think in general we want to keep the namespace separate
[05:03] <Keybuk> and I think it's never useful to say "on JOBNAME" and get started whenever that job changes state
[05:04] <wasabi_> The only reason I was thinking the other way was for our reusable complex event stuff.
[05:04] <Keybuk> but it's potentially useful to have "on STATE" (on failed) and get started whenever any job reaches that state
[05:04] <Keybuk> I don't think there's much semantic difference between
[05:04] <wasabi_> /etc/event.d/some-reusable-state-machine
[05:04] <Keybuk>     from started apache until stopping apache
[05:04] <Keybuk> and
[05:04] <Keybuk>     from apache started until apache stopping
[05:04] <Keybuk> which is the only real difference
[05:04] <wasabi_> Yeah. Agreed.
[05:04] <Keybuk> the reusable complex event stuff defines states which have the various events
[05:04] <wasabi_> I'm on board now. ;)
[05:04] <Keybuk> not a single up/down event
[05:05] <Keybuk> the cute thing about that is you can define pre-start and post-stop scripts for your reusable state machines <g>
[05:05] <wasabi_> Yeah.
[05:05] <Keybuk> of course, this all means that /etc/event.d isn't the right name anymore
[05:05] <Keybuk> it's a directory that defines jobs, services, tasks and states
[05:06] <wasabi_> But not events. ;)
[05:06] <Keybuk> I agree that /etc/event.d/FOO implies that FOO is an event, and the content of the file is what happens on it
[05:06] <wasabi_> Explicitly not events, yet we call it event.d hehe
[05:06] <Keybuk> so I think we should rename that directory
[05:06] <_ion> TBH, i was never very fond of the name "event.d".
[05:07] <wasabi_> Well, we need a name which better describes { jobs, services, tasks and states }
[05:08] <Keybuk> http://upstart.ubuntu.com/wiki/JobEvents
[05:08] <Keybuk> ^ suitable for approval?
[05:08] <wasabi_> reading
[05:08] <_ion> /etc/upstart would be quite obvious, but perhaps that would be better preserved for possible configuration of upstart itself, such as the profiles spec.
[05:09] <wasabi_> I'm curious how internally you will deal with respawning.
[05:09] <Keybuk> wasabi_: I'm edging closer and closer to dropping it entirely from the internal state
[05:09] <wasabi_> You have the concept of a goal, which is essentially an enum set on a job, and the job works towards that state.
[05:09] <wasabi_> Ahh.
[05:09] <Keybuk> I think that respawn just indicates that the job doesn't change goal when it dies
[05:09] <wasabi_> But in the case of restart, your goal is started, but you have to instruct the machine to cycle to that.
[05:09] <Keybuk> we can still kick it into stopping, and let it come back as if it had been manually restarted
[05:10] <wasabi_> True.
[05:10] <Keybuk> so it'll go stopping -> starting -> started
[05:10] <Keybuk> actually, it'll go failed -> stopping -> starting -> started
[05:10] <Keybuk> I sometimes wonder whether someone with far more forethought than I wrote it :p
[05:10] <wasabi_> You'd kick it into post-stop, basically.
[05:10] <Keybuk> right
[05:10] <_ion> "Events emitted as part of a job state change are currently named after the job, with a suffix indicating the new state."
[05:10] <wasabi_> And it would just cycle back around naturally.
[05:10] <_ion> Isn't that the other way around?
[05:10] <Keybuk> _ion: apache/started 
[05:11] <_ion> Sorry, i missed the word "currently" and misinterpreted the sentence.
[05:12] <Keybuk> I usually try in the summary to first say how things are, then say what the spec proposes
[05:15] <_ion> "it'll go failed -> stopping -> starting -> started"  Shouldn't "stopped" be there after "stopping"?
[05:16] <Keybuk> err
[05:16] <Keybuk> yes
[05:19] <_ion> Have i understood this correctly:
[05:21] <_ion>  When admin stops a job: "stopping foo", pre-stop script, kill proces, post-stop script, "stopped foo"
[05:22] <_ion>  When a process exits by itself: "failed foo exitval" IF it failed, "stopping foo", pre-stop script, post-stop script, "stopped foo"
[05:22] <Keybuk> yes
[05:23] <wasabi_> It might be worth thinking about removing "failed", and replacing it with a third argument to "stopping".
[05:23] <wasabi_> I might be totally offbase there.
[05:23] <_ion> Then "foo" would need to know what exit value "bar" has when it fails or doesn't fail.
[05:24] <wasabi_> If it's set to respawn, any exit code is a failure.
[05:24] <wasabi_> Even 0.
[05:24] <wasabi_> At least, that's how I understand it.
[05:24] <wasabi_> Maybe I'm wrong there too.
[05:25] <Keybuk> correct
[05:25] <Keybuk> or any value in normalexit
[05:26] <wasabi_> Consider this. A piece of software, such as a java application server (which I can attest operates this way), which has a built in shutdown/startup interface.
[05:26] <wasabi_> So, it's possible to shutdown this server using it's built in web interface. This does not instruct upstart to in fact shut it down.
[05:27] <wasabi_> It could, but any such patches to do so would have to be written.
[05:27] <wasabi_> Instead, it terminates normally with exit 0.
[05:27] <wasabi_> Even though you want it to respawn on crash.
[05:27] <wasabi_> So, basically, you would desire upstart to "respawn on !0"
[05:28] <Keybuk> right
[05:28] <Keybuk> respawn
[05:28] <Keybuk> normal exit 0
[05:28] <Keybuk> (this works today)
[05:28] <wasabi_> Ahh. Cool.
[05:29] <wasabi_> So, that would result in upstart running post-stop, and emitting stopping and stopped.
[05:29] <Keybuk> yes
[05:29] <wasabi_> Nice.
[06:47] <Keybuk> wasabi: what if a post-start script fails?
[06:47] <Keybuk> remind me
[06:49] <Keybuk> I think your description says it kills the process
[08:16] <wasabi_> I think if post-start fails, it would proceed to "stopped" along normal paths.
[08:17] <wasabi_> Hmm. Guess not./
[08:17] <wasabi_> Guess it would skip to stop (bypassing pre-stop)
[08:17] <wasabi_> kill the process, then post-stop.
[08:51] <Keybuk> what about if the pre-stop fails?
[09:07] <Keybuk> which is kinda interesting
[09:07] <Keybuk> assuming we issue the stopping event first, and hold on that, then things will need to be restarted
[09:08] <Keybuk> so you'd have to go stopping -> starting -> started again
[09:08] <Keybuk> without actually doing anything :p
[09:08] <Keybuk> alternatively one could wait to issue the stopping event until after pre-stop, but that negates the pre-stop being used to instruct the server to shut down safely
[09:25] <wasabi_> pre-stop wouldn't be used to instruct it to shut down.
[09:25] <wasabi_> It would be used to determine if it should actually shutdown.
[09:25] <wasabi_> Maybe that's what we're missing?
[09:25] <wasabi_> So, it isn't in fact going to stop until pre-stop says it can.
[09:26] <Keybuk> the trouble with that is that you've already issued the stopping event, haven't you?
[09:26] <Keybuk> or do you wait until pre-stop says you can?
[09:26] <Keybuk> I can see both uses for the script
[09:28] <wasabi_> Hmmm. Also makes me wonder if we in fact need a "start"/"stop" script seperatly from exec.
[09:29] <wasabi_> pre-stop i think is and idea we had simply to prevent stopping.
[09:29] <wasabi_> I'm not even sure that is even neccassary.
[09:29] <wasabi_> I'd say, if there is some actual shell script that is run that iniates the stop, it might be seperate from all of this, and a companion with "exec"
[09:29] <wasabi_> exec foo
[09:30] <wasabi_> stop script
[09:30] <wasabi_>    do something to kill foo
[09:30] <wasabi_> end script
[09:33] <wasabi_> pre-start;start;post-start,  pre-stop;stop;post-stop,  where start and stop can run at the same time. Each can be expressed by "name {exec|script}"
[09:34] <wasabi_> So, exec, logically, becomes "start exec".
[09:34] <wasabi_> JUst like we would have "post-start exec", or various other uses.
[09:34] <Keybuk>  * all works fine: starting, started, stopping, stopped
[09:34] <Keybuk>  * pre-start fails: starting, failed, stopping, stopped
[09:34] <Keybuk>  * post-start fails: starting, failed, stopping, stopped
[09:34] <Keybuk>  * binary fails: starting, failed, stopping, stopped
[09:34] <Keybuk>  * binary respawns: starting, started, failed, stopping, starting, started
[09:35] <wasabi_> start/stop are runnable at the same time. while start is still going, we are at rest.
[09:35] <Keybuk> those are the event sequences I've come up with so far
[09:35] <Keybuk> probably:
[09:35] <Keybuk>  * binary terminates badly: starting, started, failed, stopping, stopped
[09:35] <Keybuk> as well
[09:36] <wasabi_> I think there are a number of differnet things represented there which need to be thought about seperatly.
[09:36] <wasabi_> 1) emitted events
[09:36] <wasabi_> 2) "status" of job
[09:36] <Keybuk> those are simply emitted events
[09:36] <wasabi_> 3) internal status of job used to maintain state machine
[09:37] <wasabi_> Okay
[09:37] <Keybuk> trying to work out what works best
[09:37] <wasabi_> 2), the queryable statuses I see are "starting", "started", "stopping", "stopped". initctl can get the status of a job and return only those 4.
[09:37] <Keybuk> do those event sequences make sense?
[09:37] <wasabi_> 4) executable steps
[09:37] <wasabi_> Yes I believe so.
[09:38] <Keybuk> the respawn one is the odd one, as it never reaches "stopped"
[09:38] <Keybuk> it's stopping, then it's starting again
[09:38] <wasabi_> Yeah.
[09:38] <wasabi_> MIght emit stopped anyways.
[09:38] <Keybuk> I think that makes sense, if a job is "stop on stopped foo", and foo respawns, it doesn't get restarted; where a job that's "stop on stopping foo" does
[09:38] <wasabi_> Since another job may be watching for it.
[09:38] <Keybuk> the problem is working out where to emit events
[09:39] <wasabi_> You could emit stopped, but there would be no point at which you could query and return "stopped"
[09:39] <Keybuk> emitting stopped there is damned hard
[09:39] <wasabi_> Just let the mainloop run twice.
[09:39] <Keybuk> no such thing
[09:39] <wasabi_> I mean, you don't let it do that, you iterate and set it to stopped, and run the normal stopped code, which emits the event, and then it runs again immediatly after and progresses.
[09:40] <Keybuk> once it hit stopped, nothing would get it back out again
[09:40] <wasabi_> Sure, it's at stopped, but hte goal isn't stopped.
[09:40] <Keybuk> yes
[09:40] <wasabi_> So the next loop would send it to starting again
[09:40] <Keybuk> but what would pick that up?
[09:40] <Keybuk> you'd need something in the main loop checking every single job
[09:40] <Keybuk> which is damned ineffecient
[09:40] <wasabi_> Ahh.
[09:41] <wasabi_> Well, I suspect you will end up with an idle bit someplace.
[09:41] <Keybuk> right now, it flows because each change causes the next
[09:41] <Keybuk> I'm trying to drop the idle bit :)
[09:41] <wasabi_> if goal != state idle = false;
[09:41] <wasabi_> hmm. i see.
[09:41] <wasabi_> idle = (goal == state) actually.
[09:42] <wasabi_> Then always "process" jobs where !idle, after work, reset idle again.
[09:42] <wasabi_> 4) executable steps. these are basically PIDs that are being tracked.
[09:43] <wasabi_> 4) pre-start, start, post-start, pre-stop, stop, post-stop
[09:43] <wasabi_> They can be expressed as "name [exec|script]  ..."
[09:43] <wasabi_> start exec foo, start script\n foo\nend script
[09:44] <wasabi_> pre-start exec, pre-start script. Same stuff.
[09:44] <Keybuk> http://people.ubuntu.com/~scott/states.png
[09:48] <Keybuk> (reload)
[09:48] <Keybuk> (reload again)
[09:48] <Keybuk> follow the green lines while the goal is start
[09:48] <Keybuk> follow the red lines while the goal is stop
[09:49] <wasabi_> These are events?
[09:49] <Keybuk> states
[09:49] <wasabi_> Didn't think pre-start and such would be states.
[09:49] <Keybuk> why not?
[09:49] <Keybuk> they represent discreet points in the lifecycle
[09:50] <wasabi_> okay i see
[09:52] <Keybuk> starting is where we fork the process
[09:52] <Keybuk> stopping is where we kill it
[09:52] <Keybuk> we emit the "started" event when we hit "running"
[09:52] <Keybuk> and the "stopped" event when we hit "waiting"
[09:52] <Keybuk> where to emit the starting and stopping events is the tricky one <g>
[09:52] <wasabi_> I might say we emit the stopped event when we finish post-stop.
[09:52] <Keybuk> right now I have them being emitted when the goal changes, so completely outside that diagram
[09:53] <Keybuk> doesn't work if you don't have a post-stop
[09:53] <wasabi_> and we emit the started event when we finish post-start, to keep it simple.
[09:53] <wasabi_> The machine would always progress through post-stop, but if there was no post-stop PID to run/track, it would just be done.
[09:53] <wasabi_> And on completion, it emits event.
[09:53] <Keybuk> it'd enter post-stop, but then you'd need some kind of "ok, what state was I just in?" thing
[09:53] <wasabi_> Not really, always, at the end of post-stop, emit stopped event.
[09:54] <wasabi_> Regardless of what happened previously.
[09:54] <Keybuk> no such thing as "end of"
[09:54] <wasabi_> You'd want to emit stopped on a respawn.
[09:54] <Keybuk> we define an end of a state by changing to a different one
[09:54] <Keybuk> see, I'm not sure we do
[09:54] <wasabi_> Sure there is. End of just just hte last step in the small machine known as "post-stop
[09:54] <Keybuk> why does respawn need to say the job is stopped?
[09:54] <Keybuk> it never really is
[09:54] <wasabi_> Functionally it isn't available, or has gone up and down.
[09:54] <wasabi_> And thus you would have to reconnect.
[09:54] <wasabi_> nm/dbus.
[09:55] <Keybuk> right, but I think anything that connects will be hanging on the started and stopping events
[09:55] <Keybuk> NOT the starting or stopped events
[09:55] <Keybuk> because those implicitly don't allow connection
[09:55] <wasabi_> nm could do from (dbus started until dbus stopping) or (dbus started until dbus failed)
[09:55] <wasabi_> but that would be a bit obnoxious.
[09:55] <Keybuk> you'd always get stopping
[09:55] <wasabi_> Hmm. the blue line skips over it
[09:56] <Keybuk> you're confusing a state with an event
[09:56] <Keybuk> that's probably my fault :p
[09:56] <Keybuk> those stopping and starting are just the interim states, nothing to do with the events
[09:56] <Keybuk> I haven't renamed them yet
[09:56] <wasabi_> that diagram should have events hanging off of each step.
[09:56] <wasabi_> heh
[09:56] <Keybuk> that doesn't work if we don't have an event for each step :p
[09:56] <wasabi_> Okay, so stopped would not be emitted... so in that case:
[09:56] <Keybuk> the point is that we're having events to indicate which way round we're going, *not* where we are
[09:57] <wasabi_> from (dbus starting until dbus stopped) or (dbus starting until dbus failed)
[09:57] <wasabi_> Since stopped isn't emitted when failed is.
[09:57] <wasabi_> But the conditition is functionally the same.
[09:57] <Keybuk> ah
[09:57] <Keybuk> from starting dbus until stopped dbus
[09:57] <wasabi_> ie no service running, can't connect to it.
[09:57] <Keybuk> ^ I don't need to connect to dbus, just be around when it is  (and it should wait for me to be around)
[09:57] <wasabi_> dbus is a bad example there.
[09:57] <wasabi_> It was just in my buffer and I didn't want to retype.
[09:57] <Keybuk> better example
[09:58] <Keybuk> from starting apache until stopped apache
[09:58] <wasabi_> Yeah.
[09:58] <Keybuk> apache needs me to be started first, and needs to be stopped before I am
[09:58] <Keybuk> the counter-example is
[09:58] <Keybuk> from started dbus until stopping dbus
[09:58] <Keybuk> I need dbus to be around, and I don't want dbus to be stopped until I am
[09:58] <wasabi_> {...dbus...{...nm...}...}
[09:59] <Keybuk> our first example wouldn't get restarted if apache respawned (no need, apache depends on it, not the other way around)
[09:59] <Keybuk> our second example would get restarted whenever dbus respawned
[09:59] <wasabi_> {...tomcat...{...apache...}...}
[10:00] <wasabi_> Yeah I think you're right. If tomcat can run without apache, then it doesn't matter if it knows that apache just died.
[10:00] <wasabi_> Because apache will just come back.
[10:00] <wasabi_> But the situation described is still right. tomcat will always be running while apache is.
[10:00] <Keybuk> from started foo until stopped foo -- I suspect this will be rare; it implies that foo must start first, but you don't really need foo, as it's ok for it to stop
[10:01] <Keybuk> from starting foo until stopping foo -- odd, foo has to wait for you to start, and wait for you to stop -- some kind of strange hold; this works in the respawn example though
[10:01] <wasabi_> {foo  {bar   }foo   ?bar
[10:02] <wasabi_> Here's an interesting thing.
[10:02] <wasabi_> dbus will be considered started, and nm will launch.
[10:03] <wasabi_> But dbus might not have actually opened it's socket and been completely prepared.
[10:03] <Keybuk> that's what the post-start script is for, and why the started event isn't emitted until that finishes
[10:03] <wasabi_> And hence post-start can hold nm from starting until dbus is sure it's up.
[10:03] <wasabi_> And that is just totally kick ass.
[10:03] <wasabi_> Easy race elimination.
[10:04] <Keybuk> pre-stop is the tricky one
[10:04] <Keybuk> do we emit stopping before pre-stop, and wait for other jobs to finish first?
[10:04] <wasabi_> Yeah, interesting.
[10:04] <Keybuk> or do we run pre-stop first, and then only emit stopping after - waiting for other jobs to finish before killing the process?
[10:06] <wasabi_> I think that's probably best.
[10:09] <Keybuk> which means the stopping event is tricky
[10:15] <wasabi_> 1) execute and wait for pre-stop 2) if going to stop emit and wait for stopping, else reset back to started 3) execute and wait for stop (procedure to terminate process) 4) execute and wait for post-stop
[10:22] <Keybuk> http://people.ubuntu.com/~scott/states.png
[10:22] <Keybuk> reload again
[10:22] <Keybuk> follow the green lines when the goal is start
[10:22] <Keybuk> follow the red lines when the goal is stop
[10:22] <Keybuk> failure of a step sets the goal to stop
[10:23] <Keybuk> note:
[10:23] <Keybuk> running can terminate normally, and change the goal to stop (the red line out marked "normal")
[10:23] <Keybuk> this goes to pre-stop
[10:24] <Keybuk> running can terminate badly, and change the goal to stop (the red line out marked "failed")
[10:24] <Keybuk> err
[10:24] <Keybuk> sorry
[10:24] <Keybuk> the one marked failed is supposed to be marked "terminated"
[10:24] <Keybuk> the normal one is a stop request or event
[10:24] <Keybuk> the idea there is that you skip pre-stop and "kill process" if the process died
[10:25] <Keybuk> there's a red and green line in that direction, because respawn doesn't change the goal
[10:25] <Keybuk> pre-stop can change the goal back to start, so there's a green line back to running again
[10:42] <Keybuk> does that look right?
[10:45] <wasabi_> still parsing
[10:45] <wasabi_> between writing an application deployment lifecycle policy and procedures document for the audit guy. blah.
[10:47] <wasabi_> Is there a way in dotty to make a big grouping of pieces of this?
[10:47] <Keybuk> I think so, yes
[10:47] <wasabi_> Like, off to the right side, a big line which says what parts are in a group. stopped, starting, started, stopped.
[10:48] <Keybuk> what would be in those groups?
[10:48] <wasabi_> stopped would be "waiting"
[10:48] <Keybuk> ?
[10:48] <wasabi_> starting would be [emit starting, pre-start, exec process, post-start] 
[10:49] <wasabi_> started would be [emit-started, running, pre-stop] 
[10:49] <wasabi_> stopping would be the rest. get it?
[10:49] <Keybuk> I'll see what I can make it do :)
[10:49] <wasabi_> What I mean, is representing the queryable state of the job at every given point.
[11:00] <Keybuk> reload
[11:00] <Keybuk> though dot mangled that a bit :p
[11:08] <Keybuk> right bed, will mull on that a bit
[11:08] <Keybuk> nite