pidfile

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 20, 2021 License: MIT Imports: 7 Imported by: 0

README

= pidfile-go
:toc:

https://pkg.go.dev/github.com/Xiami2012/pidfile-go[image:https://pkg.go.dev/badge/github.com/Xiami2012/pidfile-go.svg[Go Reference]]

This is a go package to manage your instance/service's PID file.

See https://unix.stackexchange.com/questions/12815/what-are-pid-and-lock-files-for for what a PID
file is been used for.

== Install

`go get github.com/Xiami2012/pidfile-go@latest`

== Basic usage

[source,go]
----
func main() {
	if err := pidfile.Write("/run/your_instance_name.pid"); err != nil {
		if errors.Is(err, pidfile.ErrPIDFileInUse) {
			fmt.Printf("Instance/Service is already running. Exiting.")
			os.Exit(1)
		}
		panic(fmt.Sprintf("Failed to create PIDFile: %s\n", err.Error()))
	}
	defer pidfile.Remove("/run/your_instance_name.pid")
}
----

== Why reinventing the wheel

Once I have a daemon running in system without registering to any system service manager (run by
some scripts during boot).

To add a self-update feature, I need to know the old running PID and gracefully kill it before
running the updated one.

Searched and didn't find a package having something like GetPID() which does both reading the PID
file and verifies it is running the desired process.

== TODO

* Allow to specify compared executable name instead of current process's
* Add lock version APIs (By using flock / LockFile)

Documentation

Overview

Package pidfile provides a way to manage your PID file.

PID file is a file (usually with .pid file extension) with your running program's PID as its content. It is used for both avoiding running multiple same instances and managing the current running instance/service (sending signals).

Example

The most simple usage is to call Write on startup and Remove on shutdown.

// In func main
if err := pidfile.Write("/run/your_instance_name.pid"); err != nil {
	if errors.Is(err, pidfile.ErrPIDFileInUse) {
		fmt.Printf("Instance/Service is already running. Exiting.")
		os.Exit(1)
	}
	panic(fmt.Sprintf("Failed to create PIDFile: %s\n", err.Error()))
}
defer pidfile.Remove("/run/your_instance_name.pid")
Output:

Example (GetRunningPIDValid)

Use GetRunningPIDValid to read a PID file and verifies it is valid (process is running and has the same executable name with current process)

pid, err := pidfile.GetRunningPIDValid("/run/your_instance_name.pid")
if err == nil {
	fmt.Printf("Found an existing instance/service with pid: %d\n", pid)
}
Output:

Example (UseStruct)

To avoid writing pidfile's path every time, use PIDFile struct.

// In func main
mypidfile := pidfile.PIDFile{Filepath: "/run/your_instance_name.pid"}
if err := mypidfile.Write(); err != nil {
	if errors.Is(err, pidfile.ErrPIDFileInUse) {
		fmt.Printf("Instance/Service is already running. Exiting.")
		os.Exit(1)
	}
	panic(fmt.Sprintf("Failed to create PIDFile: %s\n", err.Error()))
}
defer mypidfile.Remove()
Output:

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrEmpty                 = errors.New("empty PIDFile struct (no Filepath given)")
	ErrProcNotExists         = errors.New("process not exists")
	ErrProcNotSameExecutable = errors.New("process is likely not running the same executable")
	ErrPIDFileInUse          = errors.New("pidfile is in use by another process")
)

Functions

func GetRunningPID

func GetRunningPID(filepath string) (int, error)

GetRunningPID constructs a PIDFile and calls its GetRunningPID. See PIDFile.GetRunningPID for details.

func GetRunningPIDValid

func GetRunningPIDValid(filepath string) (int, error)

GetRunningPIDValid constructs a PIDFile and calls its GetRunningPIDValid. See PIDFile.GetRunningPIDValid for details.

func Remove

func Remove(filepath string) error

Remove constructs a PIDFile and calls its Remove. See PIDFile.Remove for details.

func RemoveForce

func RemoveForce(filepath string) error

RemoveForce constructs a PIDFile and calls its RemoveForce. See PIDFile.RemoveForce for details.

func SendInterrupt

func SendInterrupt(pid int) error

SendInterrupt sends a Ctrl-C event (SIGINT) to the specified process.

It supports both unix and windows.

func Write

func Write(filepath string) error

Write constructs a PIDFile and calls its Write. See PIDFile.Write for details.

func WriteForce

func WriteForce(filepath string) error

WriteForce constructs a PIDFile and calls its WriteForce. See PIDFile.WriteForce for details.

Types

type PIDFile

type PIDFile struct {
	Filepath string
}

PIDFile holds a file path for further related operations.

func (PIDFile) GetRunningPID

func (f PIDFile) GetRunningPID() (int, error)

GetRunningPID reads PID from file and verifies it indicates a running process.

On success, it returns the pid of running process. Otherwise, PID 0 and error is returned.

func (PIDFile) GetRunningPIDValid

func (f PIDFile) GetRunningPIDValid() (int, error)

GetRunningPIDValid acts like GetRunningPID and additionally verifies it has the same executable name with the current process.

func (PIDFile) Remove

func (f PIDFile) Remove() error

Remove removes the PID file if GetRunningPIDValid returns PID of current process.

func (PIDFile) RemoveForce

func (f PIDFile) RemoveForce() error

RemoveForce removes the PID file. This is almost the same with os.Remove except it returns nil if the PID file does not exist.

func (PIDFile) Write

func (f PIDFile) Write() error

Write writes PID of current process to the file if GetRunningPIDValid returns PID 0.

func (PIDFile) WriteForce

func (f PIDFile) WriteForce() error

WriteForce writes the PID file with PID of current process.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL