/
cleanup.go
58 lines (47 loc) · 1.4 KB
/
cleanup.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*
GoCleanup: kinda like atexit()...
GoCleanup packages allows you to register cleanup functions.
These are called whenever the current process receives a SIGINT or SIGTERM
You can also invoke the cleanup functions by calling Cleanup().
Unfortunately, it is not possible for cleanup to intercept calls to os.Exit() and perform cleanup befor the
process exits. Instead of os.Exit, you can use cleanup.Exit()
Cleanup is especially useful when forking off external processes. You can register
callbacks with this package to tear down these external processes.
*/
package gocleanup
import (
"os"
"os/signal"
"syscall"
)
var cleanupFuncs []func()
var capturingSignals bool
//Register a cleanup function. This will be called when:
//- a call is made to Cleanup()
//- a call is made to Exit()
//- the current process receives SIGINT or SIGTERM
func Register(f func()) {
cleanupFuncs = append(cleanupFuncs, f)
if !capturingSignals {
capturingSignals = true
go func() {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM)
<-c
Exit(1)
}()
}
}
//Cleanup invokes all registered cleanup functions
//all registered cleanup functions are subsequently removed
func Cleanup() {
for _, f := range cleanupFuncs {
f()
}
cleanupFuncs = []func(){}
}
//Exit invokes all registered cleanup functions, then exits
func Exit(status int) {
Cleanup()
os.Exit(status)
}