Make Go service run properly
By: Petr Jahoda
Tags: Golang, Go, Docker, Tutorial, Programming

Update the code

As we like to know the state of the service in every instance of time, when code is running, we will add two boolean variables, that show us their statuses, for example using fmt.Println() .

Add variables

Those two variables we will call serviceIsRunning and programIsRunning . We start with adding those two variables just below the import section. There will add third variable of type sync.Mutex . This variable takes responsibility of synchronisation, when writing or reading to/from those two boolean variables (when two lines of code want to update the variable serviceIsRunning in the same exact time, mutex allows only one line of code to make the change and then invite the second line of code to make its change).

In this particular example we won’t be writing to one variable from two different sections of code, so this sync.Mutex is not necessary now, but we will use it.

As you see, all three variables are underlined with red. The reason is again the same: we are not using those variables anywhere.

Update the methods

At first, we start with serviceIsRunning .

Update the Start() method with code below. Initially, the variable serviceIsRunning is set to false. After the service started, we set it to true. Before setting, we lock this serviceIsRunning variable with writingSync.Lock() , so any other future line in the program (that wants to write to the same variable) has to wait until this writingSync unlocks back our serviceIsRunning variable. Now, when our service starts, our variable serviceIsRunning is set properly.

We do something similar with the Stop() method. No more talking, the code is below and the idea is the same.

Now it’s time to play with the programIsRunning variable. We move to the run() method. At first, we want to make sure, that our production code will run only if the service is already running. See code below, nothing special. Adding one condition: the production code runs only when variable serviceIsRunning is true.

You can now test your code. It will work the same as before, so it looks like we make no progress, but believe me, we do make a progress.

Update production code

To see the effect in work, update the time.Sleep() method, so it will wait for 2 second (you can try 5 second to see the effect better).

We play again with that mutex variable and, for a first time, with the programIsRunning variable. Code below shows the changes.

This code takes about two seconds to finish. In the beginning, we set programIsRunning to true (so everywhere in our code we can check if this program is running). And after this loop is done, we set this variable programIsRunning again to false.

After all this is done, you can check if the program runs. And it runs, but… still no effect.

Final fine tuning

Let’s get back to our Stop() method. Update the code with a new loop. This new loop simply waits for the programIsRunning variable to be false (that means: it waits for the production code to finish itself).

And only then the loop will end the Stop() method.

Final test

Run the code now (if you see no effect, increase the time.Sleep() in run() method to 5 seconds).

Hopefully you’ll see the effect. When you try to stop the program (simulating someone stops the service), the program waits for the production code to end properly, and only after that, the service will shut itself down.

For example: if you increase that sleeping in run() method to 10 second, you will see much more Medium service stopping ... lines. Of course, that depends on when you stop the program.

Summary

After reading this article you know, how to …