Skip to content

Ensures that only one instance of the executable is running

License

Notifications You must be signed in to change notification settings

crgimenes/single

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

single

Build Status Go Report Card GoDoc Go project version MIT Licensed

Ensures that only one instance of the executable is running

Install

go get github.com/crgimenes/single

Examples

package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/crgimenes/single"
)

const lockfile = "signal.pid"

func main() {
	err := single.Start(lockfile)
	if err != nil {
		if os.IsExist(err) {
			fmt.Println("another instance of the executable is already running")
			os.Exit(1)
		}
		fmt.Println(err)
		os.Exit(1)
	}
	go func() {
		sc := make(chan os.Signal, 1)
		signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM)
		<-sc
		errc := single.Stop(lockfile)
		if errc != nil {
			fmt.Println(errc)
			os.Exit(1)
		}
		fmt.Println("\n\nhave a nice day!")
		os.Exit(0)
	}()

	fmt.Println("Press ^C to terminate")

	for {
		time.Sleep(1 * time.Second)
		fmt.Print(".")
	}
}

For a process that does not run indefinitely, besides intercepting the signals use defer in the main function to ensure that street completion routine will always be executed

package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/crgimenes/single"
)

const lockfile = "signal.pid"

func shutdown() {
	err := single.Stop(lockfile)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	fmt.Println("\n\nhave a nice day!")
	os.Exit(0)
}

func main() {
	err := single.Start(lockfile)
	defer shutdown()
	if err != nil {
		if os.IsExist(err) {
			fmt.Println("another instance of the executable is already running")
			os.Exit(1)
		}
		fmt.Println(err)
		os.Exit(1)
	}
	go func() {
		sc := make(chan os.Signal, 1)
		signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM)
		<-sc
		shutdown()
	}()

	fmt.Println("Processing...")
	time.Sleep(3 * time.Second)
}