M
M
memba2015-09-29 00:11:29
go
memba, 2015-09-29 00:11:29

How would you check for a second instance of the program to run?

It is necessary to organize a simple check for the launch of the second instance of the program and, if possible, block it.
First:
I would create a PID file and put an exclusive lock on it. Accordingly, if the file is locked, then the application is already running. Problem: as I see it, Go does not implement a cross-platform way to block a file out of the box (syscall.Flock is not supported under Windows), writing a crutch is not reasonable.
Second:
I would set the Mutex. Problem: as I see it, Go does not support named mutexes and, accordingly, they are available only in the aisles of one process.
Third:
I would occupy some port and every time I start the program I would check its busyness. Problem: It is not very good to clog the port, especially since it may already be busy initially. And there is no easy way in Go to check if a port is available. You can only connect to it using net.Listen("tcp", ":8080"), check the connection result and immediately disconnect.

Answer the question

In order to leave comments, you need to log in

6 answer(s)
V
Vitaly Filinkov, 2015-09-29
@memba

The third way is the most kosher and the most versatile.

T
Tyranron, 2015-09-29
@Tyranron

I do not like the 3rd option, because it does not solve the problem entirely. The port to listen to is more of a configuration parameter, which means you need to think about whether nothing bad will happen when you change the port and restart (usually it shouldn't, but it doesn't have to be done once in a while). What if the daemon doesn't need to listen on any port at all? Not universal.
Alas, there is no cross-platform solution out of the box, yes. When I cooked my craft, then I was only interested in *nix-like platforms, the good old PID file with syscall.Flock was enough for me. What I saw in other solutions, more cross-platform - people bothered with platform specific code, for Windows they used process registration as a service. Wrapping this into a separate package with a single interface and platform specific compilation is not at all difficult in the case of Go. To work with Windows services, there is a wonderful, albeit not included in the standard lib, but still the official golang.org/x/sys/windows/svc package , and you don’t even need to use pure syscalls.
Also take a look at this thread , there is just about a solution for Windows in the form of a semaphore / mutex, similar to what Vladimir Martyanov pointed outin a comment to your question and what you indicated in the 2nd paragraph.

I
index0h, 2015-09-29
@index0h

Pidfile -> check if the process exists by pid -> if it already exists:
* yes -> close
* no -> delete pidfile if it exists -> run
-----
There is an alternative launch option: via supervisor

S
Saboteur, 2015-09-29
@saboteur_kiev

memba : The
PID file does not need to be locked.
Look at what lies inside the /var/run
files, all pid files inside store the process number. Therefore, the file does not need to be locked, you just need to check for the existence of the file, read the process number from it and check if such a process exists.
If it does not exist, then the previous execution of the program was completed incorrectly.
The file is called PID because it contains the PID ;)

A
Andrey K, 2015-09-29
@mututunus

You can simply check the PID file yourself at startup ..

R
RomanPyr, 2015-09-30
@RomanPyr

On Unix you can use unix sockets (like ssh-agent does), on windows named pipes. For the latter:
https://github.com/natefinch/npipe

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question