Reputation: 91
We do our deployments with capistrano. Our website consists of a rails frontend and java API backend.
I have a situation where the java API application takes about 15 minutes to start up and the rails application can't run without it. Initially I tried to loop within capistrano using the capture command to wait until the application started listening on the port (8080 in our case):
desc "Start api"
task :api, :roles => :api do
run("cd #{home_api} && ./api.sh start > /dev/null 2>&1 &")
sleep 1
api_status = nil
until api_status
api_status = capture("echo `netstat -tln | grep 8080`")
sleep 60
end
puts "API Started successfully."
end
However, capture only runs on one server (we have several API machines) and if that one finishes starting up before the others the deployment may proceed before all the API machines are ready.
I need something that will wait for a port to be open on all servers matching the specified role before moving on.
Upvotes: 4
Views: 3995
Reputation: 91
Here's how I am currently doing this:
Using 'run' to execute some shell commands that won't return until the port is open (or until 30 minutes have passed in this case.) This will run on all the matching servers and won't continue until all of them have completed.
desc "Start api"
task :api, :roles => :api do
run("cd #{home_api} && ./api.sh start > /dev/null 2>&1 &")
sleep 1
run("for i in {0..60}; do echo \"Waiting for API to start\"; if [[ \"\" != \"$\(netstat -an |grep 8080\)\" ]]; then break; fi; sleep 30; done")
end
I'm curious to see how other people are doing this, there surely is a better way?
Upvotes: 4