Quantcast
Channel: Planet Ubuntu
Viewing all articles
Browse latest Browse all 17727

Upstart Development Blog: Events are like Hooks

$
0
0

In the previous posts we’ve looked at how Upstart’s events can be used as signals and as methods, in this post we’ll look at the third way in which they can be used: as hooks.

It’s worth a recap to fully explain how this works.  Recall that signals are notifications that something happened on the system or changed about it; and that the most important thing about signals is that they have no duration and no follow-up.  The emitter doesn’t care whether the signal is handled, or how long it takes to handle.

A signal event is emitted with the –no-wait parameter to initctl emit:

initctl emit --no-wait control-alt-delete

And a signal event is matched with start on or stop on, since the emitter isn’t waiting, it doesn’t make any difference whether a task uses the task keyword or not.

start on control-alt-delete
exec shutdown -r now

In contrast, when events are used as methods, the result is important since the emitter is creating the event in order for a change to happen.  The job is expected to perform that change, and initctl emit waits for it to complete before returning to the shell.

initctl emit runlevel RUNLEVEL=2

Because something is waiting, it’s more important that we use the task keyword if initctl should wait for the job to complete.  Of course, it’s perfectly legal for a method event to be used to start or stop a service as well, in which case it wouldn’t be used.

start on runlevel
task
exec /etc/init.d/rc $RUNLEVEL

So now we look at hooks.  A hook is somewhere between a signal and a method.  It’s a notification that something changed on the system, but unlike a signal, the emitter waits for it to complete before carrying on.

The purpose of a hook is to allow other tasks, services (or packages) to hook into processing to perform its own actions before or after some change has taken place.

Both initctl emit and the start on or stop on keywords look the same as if the event as being used as a method, the difference is that the caller isn’t expecting something to happen as a result of the event, but is allowing the system to perform any processing before the caller itself makes something happen.

Things are never clear without examples, let’s use the process of unmounting filesystems on shutdown; that’s a popular one right now.  How would a hook help?  Let’s place a call to initctl emit before the call to umount -a:

initctl emit unmounting-filesystems
umount -a

Since we didn’t use –no-wait, the initctl emit call will block while Upstart works and any services are started or stopped and any tasks run.  Now we can use this hook to ensure things are done before the filesystem is unmounted, for example we can stop services:

stop on unmounting-filesystems

And we can even run tasks which must run and complete before the filesystem is unmounted:

start on unmounting-filesystems
task
script
  # last-minute-cleanup
end script

There are plenty of hook events in any Upstart system, beginning with the starting and stopping events emitted by Upstart itself and including events such as mounting and mounted emitted during initial filesystem construction.  Take a look at the manual pages for those events, section 7 if you recall from earlier.

So as you can hopefully see, Upstart’s events can be used to fulfill all three common programming patterns, simply by slight variation in the command used to emit them.


Viewing all articles
Browse latest Browse all 17727

Trending Articles