0

I have the following test configuration file for an upstart service, running on Ubuntu 14.04:

expect stop
chdir /home/joe/Projects/Marketplace
env RAILS_ENV="development"
script
  ruby -e "STDOUT.sync=true; puts 'loading...'; sleep 5; Process.kill(:STOP, Process.pid); 5.times { puts 'running'; sleep 3 }" > /tmp/upstart_test.log
end script

The embedded ruby script just sleeps for 5 seconds (to imitate loading), then sends itself a STOP signal, in order to notify Upstart that it is ready, and then prints 'running' a few times (to imitate some service happening). Wow Awesome. Such simple.

The problem is, when I start this "service" with start fake-service, that command hangs (waiting for the service to finish starting), and the process ends up in a stopped state, which Upstart never acknowledges or sends a 'CONT' for.

What gives??

Update: exec helps, but forking still fails

I have discovered that if, in the config file, I use exec instead of a script block to run the command that starts the "daemon", it works just fine:

expect stop
chdir /home/joe/Projects/Marketplace
env RAILS_ENV="development"
exec ruby -e "STDOUT.sync=true; puts 'loading...'; sleep 5; Process.kill(:STOP, Process.pid); 5.times { puts 'running'; sleep 3 }" > /tmp/upstart_test.log

However, if I include a fork in the script (which is the entire point of using expect stop in the first place I thought - to help Upstart determine the main process PID easily):

expect stop
chdir /home/joe/Projects/Marketplace
env RAILS_ENV="development"
exec ruby -e "STDOUT.sync=true; puts 'loading...'; sleep 5; fork { Process.kill(:STOP, Process.pid); 5.times { puts 'running'; sleep 3 } }; Process.wait" > /tmp/upstart_test.log

The Upstart documentation does have a warning about using expect with script blocks, but it is specifically talking about running multiple commands in the block being problematic, because it doesn't know which one to watch. In this case I'm only running a single command... so that doesn't help.

  • Hey so you can use a script section with expect stop, just make sure you use exec in the final part of the script. – CameronNemo Nov 17 '14 at 22:55
1

It turns out, I believe, that my understanding of expect stop was incorrect! I thought, as I stated above, that it was used (like the other expect stanzas) "to help Upstart determine the main process PID easily."

Now that I re-read the documentation, I believe what it means, where it says, "Specifies that the job's main process will raise the SIGSTOP signal to indicate that it is ready," is that the original process that is run by upstart has to raise the STOP signal, and that signal is used only to determine when the job is ready. So this expect stanza is unrelated to the other two, which are used to determine the main PID of a job that contains forks.

And the reason it doesn't work for the script block is that the script block itself forks a new shell to run its contents, so the main process is actually the parent of whatever command is run inside the block.

It all makes so much more sense now :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.