Remove AutoFile; Use go-autofile instead
This commit is contained in:
parent
1a24e6e237
commit
44f2818a3d
154
os.go
154
os.go
|
@ -7,19 +7,12 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
GoPath = os.Getenv("GOPATH")
|
GoPath = os.Getenv("GOPATH")
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
initAFSIGHUPWatcher()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TrapSignal(cb func()) {
|
func TrapSignal(cb func()) {
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
signal.Notify(c, os.Interrupt)
|
signal.Notify(c, os.Interrupt)
|
||||||
|
@ -112,153 +105,6 @@ func WriteFileAtomic(filePath string, newBytes []byte, mode os.FileMode) error {
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
|
||||||
/* AutoFile usage
|
|
||||||
|
|
||||||
// Create/Append to ./autofile_test
|
|
||||||
af, err := OpenAutoFile("autofile_test")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stream of writes.
|
|
||||||
// During this time, the file may be moved e.g. by logRotate.
|
|
||||||
for i := 0; i < 60; i++ {
|
|
||||||
af.Write([]byte(Fmt("LOOP(%v)", i)))
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close the AutoFile
|
|
||||||
err = af.Close()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
const autoFileOpenDuration = 1000 * time.Millisecond
|
|
||||||
|
|
||||||
// Automatically closes and re-opens file for writing.
|
|
||||||
// This is useful for using a log file with the logrotate tool.
|
|
||||||
type AutoFile struct {
|
|
||||||
ID string
|
|
||||||
Path string
|
|
||||||
ticker *time.Ticker
|
|
||||||
mtx sync.Mutex
|
|
||||||
file *os.File
|
|
||||||
}
|
|
||||||
|
|
||||||
func OpenAutoFile(path string) (af *AutoFile, err error) {
|
|
||||||
af = &AutoFile{
|
|
||||||
ID: RandStr(12) + ":" + path,
|
|
||||||
Path: path,
|
|
||||||
ticker: time.NewTicker(autoFileOpenDuration),
|
|
||||||
}
|
|
||||||
if err = af.openFile(); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
go af.processTicks()
|
|
||||||
autoFileWatchers.addAutoFile(af)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (af *AutoFile) Close() error {
|
|
||||||
af.ticker.Stop()
|
|
||||||
err := af.closeFile()
|
|
||||||
autoFileWatchers.removeAutoFile(af)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (af *AutoFile) processTicks() {
|
|
||||||
for {
|
|
||||||
_, ok := <-af.ticker.C
|
|
||||||
if !ok {
|
|
||||||
return // Done.
|
|
||||||
}
|
|
||||||
af.closeFile()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (af *AutoFile) closeFile() (err error) {
|
|
||||||
af.mtx.Lock()
|
|
||||||
defer af.mtx.Unlock()
|
|
||||||
|
|
||||||
file := af.file
|
|
||||||
if file == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
af.file = nil
|
|
||||||
return file.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (af *AutoFile) Write(b []byte) (n int, err error) {
|
|
||||||
af.mtx.Lock()
|
|
||||||
defer af.mtx.Unlock()
|
|
||||||
if af.file == nil {
|
|
||||||
if err = af.openFile(); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return af.file.Write(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (af *AutoFile) openFile() error {
|
|
||||||
file, err := os.OpenFile(af.Path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
af.file = file
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
var autoFileWatchers *afSIGHUPWatcher
|
|
||||||
|
|
||||||
func initAFSIGHUPWatcher() {
|
|
||||||
autoFileWatchers = newAFSIGHUPWatcher()
|
|
||||||
|
|
||||||
c := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(c, syscall.SIGHUP)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
for _ = range c {
|
|
||||||
autoFileWatchers.closeAll()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
type afSIGHUPWatcher struct {
|
|
||||||
mtx sync.Mutex
|
|
||||||
autoFiles map[string]*AutoFile
|
|
||||||
}
|
|
||||||
|
|
||||||
func newAFSIGHUPWatcher() *afSIGHUPWatcher {
|
|
||||||
return &afSIGHUPWatcher{
|
|
||||||
autoFiles: make(map[string]*AutoFile, 10),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (afw *afSIGHUPWatcher) addAutoFile(af *AutoFile) {
|
|
||||||
afw.mtx.Lock()
|
|
||||||
afw.autoFiles[af.ID] = af
|
|
||||||
afw.mtx.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (afw *afSIGHUPWatcher) removeAutoFile(af *AutoFile) {
|
|
||||||
afw.mtx.Lock()
|
|
||||||
delete(afw.autoFiles, af.ID)
|
|
||||||
afw.mtx.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (afw *afSIGHUPWatcher) closeAll() {
|
|
||||||
afw.mtx.Lock()
|
|
||||||
for _, af := range afw.autoFiles {
|
|
||||||
af.closeFile()
|
|
||||||
}
|
|
||||||
afw.mtx.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
func Tempfile(prefix string) (*os.File, string) {
|
func Tempfile(prefix string) (*os.File, string) {
|
||||||
file, err := ioutil.TempFile("", prefix)
|
file, err := ioutil.TempFile("", prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue