You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
1.7 KiB
77 lines
1.7 KiB
package proc |
|
|
|
import ( |
|
"git.diulo.com/mogfee/kit/core/threading" |
|
"git.diulo.com/mogfee/kit/logx" |
|
"os" |
|
"os/signal" |
|
"sync" |
|
"syscall" |
|
"time" |
|
) |
|
|
|
const ( |
|
wrapUpTime = time.Second |
|
waitTime = 5500 * time.Millisecond |
|
) |
|
|
|
var ( |
|
wrapUpListeners = new(listenerManager) |
|
shutdownListeners = new(listenerManager) |
|
delayTimeBeforeForceQuit = waitTime |
|
) |
|
|
|
func AddShutdownListener(fn func()) (waitForCalled func()) { |
|
return shutdownListeners.addListener(fn) |
|
} |
|
func AddWrapUpListener(fn func()) (waitForCalled func()) { |
|
return wrapUpListeners.addListener(fn) |
|
} |
|
func SetTimeToForceQuit(duration time.Duration) { |
|
delayTimeBeforeForceQuit = duration |
|
} |
|
func Shutdown() { |
|
shutdownListeners.notifyListeners() |
|
} |
|
func WrapUp() { |
|
wrapUpListeners.notifyListeners() |
|
} |
|
func gracefulStop(signals chan os.Signal) { |
|
signal.Stop(signals) |
|
logx.Info("Got signal SIGTERM, shutting down...") |
|
time.Sleep(wrapUpTime) |
|
go shutdownListeners.notifyListeners() |
|
time.Sleep(delayTimeBeforeForceQuit - wrapUpTime) |
|
logx.Infof("Still alive after %v, going to force kill the process...", delayTimeBeforeForceQuit) |
|
syscall.Kill(syscall.Getpid(), syscall.SIGTERM) |
|
} |
|
|
|
type listenerManager struct { |
|
lock sync.Mutex |
|
waitGroup sync.WaitGroup |
|
listeners []func() |
|
} |
|
|
|
func (l *listenerManager) addListener(fn func()) (waitForCalled func()) { |
|
l.waitGroup.Add(1) |
|
|
|
l.lock.Lock() |
|
l.listeners = append(l.listeners, func() { |
|
defer l.waitGroup.Done() |
|
fn() |
|
}) |
|
l.lock.Unlock() |
|
return func() { |
|
l.waitGroup.Wait() |
|
} |
|
} |
|
func (l *listenerManager) notifyListeners() { |
|
l.lock.Lock() |
|
defer l.lock.Unlock() |
|
|
|
group := threading.NewRoutineGroup() |
|
for _, listener := range l.listeners { |
|
group.RunSafe(listener) |
|
} |
|
group.Wait() |
|
}
|
|
|