On 09/14/2009 09:28 AM, Scott James Remnant wrote: > On Sat, 2009-09-12 at 19:03 -0400, Casey Dahlin wrote: > >> On 09/12/2009 12:31 PM, Scott James Remnant wrote: >>> Another interesting thing abouts events is that they too have a >>> lifecycle and different states. >>> >>> They're not just fired and forgotten: the event is kept "open" all the >>> time that jobs that it changed are in transition between levels. Only >>> once the jobs are all back at a rest level again is the event finished. >>> >> >> My earlier email on Triggers proposes doing away with this internally. >> Events are now fire-and-forget. >> > I'm not sure what you mean here, do you mean that you're removing the > blocking behaviour of events entirely? >
>From the user perspective, events still behave exactly the same way. Inside of >Upstart, events no longer block, but the way jobs respond to them has been >altered such that they appear to. > I've tried to describe what the external interface would look like, > rather than necessarily an internal implementation. It's possible to > implement events with "finished" logic in about a thousand different > ways. > > I do think that it's important that: > > 1. events are fired off once, and affect all jobs in one atomic > operation > Should still be true. > 2. once those jobs all reach a rest state, the event is "finished" and > this is notified back to the emitter of an event > In effect this is what you get. The event is now gone at this point, and it is the emission of /another/ event that causes this. For example, say that we emit an event which starts a job. The procedure is as follows: 1. job_change_goal (foojob, JOB_START) 2. If the job isn't immediately in started set a new trigger: on started foojob announce_finish (event.name, event.env) 3. free (event) > 3. and thus, consequently, events can be "failed" if jobs fail to > start/stop as a result > The amendment to the above to get this is in the trigger: on started foojob or stopping foojob announce_finish ... the announce_finish handler can then look at what specifically triggered it (including environment variables etc) and handle the finishing appropriately. > If you don't think they should behave like this, we should talk about > that first before discussion about implementation. > Probably just muddling things since the behavior is, from the user's perspective, the same :) >> Previously the logic was: >> 1) A job changes goal, and fires a "starting" event. >> 2) The job waits for the starting event to unblock. >> 3) The job continues. >> >> The new logic is: >> 1) A job changes goal and fires a starting event. >> 2) The job stops in place. >> 3) The fired event sets up a series of handlers that will cause the job >> to begin moving again when all of the responders have answered. >> > Well, this is confusing because the job doesn't "wait" for the starting > event to unblock - it simply exists the job_change_state() loop. It's > up to event_unblock() to call job_change_state() again to continue the > state transition. > > The only difference between this and your logic, I guess, is that the > call is hardcoded rather than using a function pointer. > Something like that. >> Is this a good idea? My code will be the proof :) Outwardly scary as the >> idea of these "fire, tell someone else, and forget" events is, it has >> drastically simplified the code it has touched (EventOperator itself >> will soon entirely evaporate from my branch). >> > I want to make sure we preserve the behaviour of event operator though. > There's some wonderful emergent behaviour from it. > > For example, here's how to block starting of the display manager until > another service has actually stopped: > > start on stopped mountall and starting gdm > task > D: You have some weird UI fetishes. Nonetheless, that should still work. > Scott > -- upstart-devel mailing list [email protected] Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/upstart-devel
