grim/convey

add a Destroy function to fs.Directory

2020-05-27, Gary Kramlich
7f4709517632
add a Destroy function to fs.Directory
// Convey
// Copyright 2016-2018 Gary Kramlich <grim@reaperworld.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package runtime
import (
"os"
"os/signal"
"sync"
"syscall"
"github.com/emirpasic/gods/stacks/arraystack"
log "github.com/sirupsen/logrus"
"keep.imfreedom.org/grim/convey/logging"
)
// cleanupList is a simple structure for keeping track of functions to call
// on cleanup.
type cleanupList struct {
mutex sync.Mutex
functions *arraystack.Stack
}
// newCleanupList create and initializes a cleanupList
func newCleanupList() *cleanupList {
return &cleanupList{
functions: arraystack.New(),
}
}
// Add adds a function to the cleanup list.
func (cl *cleanupList) Add(fn func(l *log.Entry)) {
cl.mutex.Lock()
defer cl.mutex.Unlock()
cl.functions.Push(fn)
}
// run will run all of the cleanup functions in the list
func (cl *cleanupList) run() {
cl.mutex.Lock()
defer cl.mutex.Unlock()
logger := logging.NewAdapter("cleanup")
it := cl.functions.Iterator()
for it.Next() {
fn := it.Value().(func(*log.Entry))
fn(logger)
}
}
// cleanupOnSignal will call State.Destroy on SIGINT or SIGTERM
func (rt *Runtime) cleanupOnSignal() {
// create a channel to receive the signal
ch := make(chan os.Signal, 1)
go func() {
// block until we get a signal, we don't care what it is so we just
// throw it away
<-ch
// call the destroy method
rt.Shutdown()
// exit with an exit code of 1
os.Exit(1)
}()
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
}
// Cleanup registers a function to be called when the state is being torn down.
func (rt *Runtime) Cleanup(fn func(l *log.Entry)) {
rt.cleanupList.Add(fn)
}