Search code examples
upstart

How to make sure a task is executed before starting different services


We have the following scenario in upstart:

We have some task called T, and some services, A and B with the following requirements:

  • T must run completely isolated from the services A and B
  • Both A and B can only run if task T has completed
  • A and B can be started independently

In simple words, T is a requirement for both A and B, but running T doesn't necessarily mean that either A or B should be started.

How can we enforce these requirements in upstart? Adding other "helper" jobs is fine, of course.


We tried the following, that doesn't work:

# T.conf
task
start on (starting A or starting B)

The problem is that if T is already running when starting B, e.g. because A is already about to start, then B will just start without waiting for T to finish. This violates the first two requirements above.


Another option is to explicitly start T from the pre-start sections of the services. However, that causes a service to fail to start, instead of waiting, if T is already being executed.


Solution

  • There is a workaround using this extra helper task (better suggestions are still welcome):

    start on (starting A or starting B)
    task
    instance $JOB
    script
        until start T; do sleep 1; done
    end script
    

    This helper job is started just about when either A or B is about to start, blocking those services. There will be one instance of this task for each service. It will block until T is successfully completed.