top of page

You will never sleep after reading this!


One common design pattern I've come across needing frequently is the ability to have dependent starts. Start service1 then start service2 if service1=running. Basically just starting services in order.

I remember back to the beginning of my career when I'd use bash to automate systems my goto was the sleep command. While super elegant (1 line of code) it doesn't scale well. Once you decide to go multithreaded the short supply of cpu resources can cause delay in running processes and what used to take 5 seconds now takes 9 seconds and now a race condition occurred. Not reliable.

service falcon_service start

sleep 10

service falcon_service2 start

It's a much better design pattern to check a condition rather than some arbitrary static amount of seconds. If we introduce a bit of IF and FOR loops and evaluate a return code of a `` system call then we end up with something like:

# let's start polling!

tcp_port=80

timeout_seconds=2

service_running=false

for((i=0; i<timeout_seconds; i++));

do if lsof -i tcp:$tcp_port | grep -i listen; then

echo "$tcp_port is listening"

check_pass=true

break

fi

sleep 1

done

if $check_pass; then

echo "service port check passed"

else

echo "service start failed after max wait of $timeout_seconds"

fi

Ok. So that works. And it works good, we aren't taxing resources. One could even implement a jitter reduction pattern to back off exponentially, which can solve some problems experienced at scale.

Ok, so isn't this kind of a huge trade off,.. look how much code this introduced. Their's two good aspects of code I try to shoot for: One, It should be able to handle external resources gracefully which this does. Two, it should be easily readable code and should only be written once.

So, instead of writing this each time, I'd modularize it. Replace the actual command lsof with a variable that gets populated on the command line with the value of an argument.

disclaimer: I will say, from a security perspective what I just said sounds really dangerous! Any executable command from the command line. What if someone down the line makes use of this code and puts a web gui on it. Some random haxxor could hose your system. Definitely use the eval statement instead of just executing a command with the system function. Always validate input! Also, reduce the attack surface by limiting the command, maybe only pass in the port number. Anyway, I hope you get my point.

At some point I'll add what I use into my git repo, so maybe I already have by the time you read this so check out my github link on my main blog page.

-Nick Skitch

Single post: Blog_Single_Post_Widget
bottom of page