grim/convey
Clone
Summary
Browse
Changes
Graph
Bump the version for release
v0.11.1
2017-10-21, Gary Kramlich
00923ff4e245
Bump the version for release
/*
* Convey
* Copyright 2016-2017 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
cleanup
import
(
"os"
"os/signal"
"sync"
"syscall"
"bitbucket.org/rw_grim/convey/logging"
"bitbucket.org/rw_grim/convey/util"
)
type
(
// List is a list of things that should happen in case the
// program receives a signal. This should be things like making
// sure temp files are deleted, volumes are destroyed, etc.
List
struct
{
funcs
map
[
string
]
Func
mutex
sync
.
RWMutex
}
// Func is a function to run on exit (it should be quick).
Func
func
()
)
// NewList will create a new List that will run all registered
// functions on SIGINT or SIGTERM.
func
NewList
()
*
List
{
var
(
ch
=
make
(
chan
os
.
Signal
,
1
)
list
=
&
List
{
funcs
:
map
[
string
]
Func
{}}
adapter
=
logging
.
NewAdapter
(
"main"
)
)
go
func
()
{
<-
ch
adapter
.
Fatal
(
"Received signal, cleaning up"
)
list
.
run
()
os
.
Exit
(
1
)
}()
signal
.
Notify
(
ch
,
syscall
.
SIGINT
,
syscall
.
SIGTERM
)
return
list
}
// Add will register a function to be invoked on system exit
// unless the returned function is called. The given function
// is wrapped in the return function, so it can be used in its
// place. This function MUST be called in order to deregister
// it on exit if it cannot be called idempotently. The order of
// functions invoked on exit is not guaranteed to be stable.
func
(
c
*
List
)
Add
(
fn
Func
)
func
()
{
c
.
mutex
.
Lock
()
defer
c
.
mutex
.
Unlock
()
name
:=
util
.
ShortID
()
c
.
funcs
[
name
]
=
fn
return
func
()
{
c
.
fire
(
name
)
}
}
func
(
c
*
List
)
fire
(
name
string
)
{
c
.
mutex
.
Lock
()
c
.
funcs
[
name
]()
delete
(
c
.
funcs
,
name
)
c
.
mutex
.
Unlock
()
}
func
(
c
*
List
)
run
()
{
c
.
mutex
.
Lock
()
defer
c
.
mutex
.
Unlock
()
for
_
,
fn
:=
range
c
.
funcs
{
fn
()
}
}