From 1f66755fd87438dc85510c22be60f2a829d7d156 Mon Sep 17 00:00:00 2001 From: Jordan Sissel Date: Wed, 16 Oct 2013 17:04:50 -0700 Subject: [PATCH] os.Rename fails on windows if the file exists. I can find no way to invoke ReplaceFile via Go, so lumberjack's registrar updates will not be atomic on Windows platform. On windows, the "old" registrar db is saved as ".lumberjack.old" --- harvester.go | 2 ++ registrar.go | 19 ++----------------- registrar_other.go | 23 +++++++++++++++++++++++ registrar_windows.go | 24 ++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 17 deletions(-) create mode 100644 registrar_other.go create mode 100644 registrar_windows.go diff --git a/harvester.go b/harvester.go index e44846b..98d6453 100644 --- a/harvester.go +++ b/harvester.go @@ -34,6 +34,8 @@ func (h *Harvester) Harvest(output chan *FileEvent) { // get current offset in file offset, _ := h.file.Seek(0, os.SEEK_CUR) + log.Printf("Current file offset: %d\n", offset) + // TODO(sissel): Make the buffer size tunable at start-time reader := bufio.NewReaderSize(h.file, 16<<10) // 16kb buffer by default diff --git a/registrar.go b/registrar.go index cc01490..1999828 100644 --- a/registrar.go +++ b/registrar.go @@ -2,8 +2,6 @@ package main import ( "log" - "os" - "encoding/json" ) func Registrar(input chan []*FileEvent) { @@ -28,25 +26,12 @@ func Registrar(input chan []*FileEvent) { Inode: ino, Device: dev, } + log.Printf("State %s: %d\n", *event.Source, event.Offset) } if len(state) > 0 { - write(state) - os.Rename(".lumberjack.new", ".lumberjack") + WriteRegistry(state, ".lumberjack") } } } -func write(state map[string]*FileState) { - log.Printf("Saving registrar state.\n") - // Open tmp file, write, flush, rename - file, err := os.Create(".lumberjack.new") - if err != nil { - log.Printf("Failed to open .lumberjack.new for writing: %s\n", err) - return - } - - encoder := json.NewEncoder(file) - encoder.Encode(state) - file.Close() -} diff --git a/registrar_other.go b/registrar_other.go new file mode 100644 index 0000000..330dbb2 --- /dev/null +++ b/registrar_other.go @@ -0,0 +1,23 @@ +// +build !windows + +package main +import ( + "encoding/json" + "os" + "log" +) + +func WriteRegistry(state map[string]*FileState, path string) { + // Open tmp file, write, flush, rename + file, err := os.Create(".lumberjack.new") + if err != nil { + log.Printf("Failed to open .lumberjack.new for writing: %s\n", err) + return + } + defer file.Close() + + encoder := json.NewEncoder(file) + encoder.Encode(state) + + os.Rename(".lumberjack.new", path) +} diff --git a/registrar_windows.go b/registrar_windows.go new file mode 100644 index 0000000..ef8cf55 --- /dev/null +++ b/registrar_windows.go @@ -0,0 +1,24 @@ +package main + +import ( + "encoding/json" + "os" + "log" +) + +func WriteRegistry(state map[string]*FileState, path string) { + tmp := path + ".new" + file, err := os.Create(tmp) + if err != nil { + log.Printf("Failed to open .lumberjack.new for writing: %s\n", err) + return + } + + encoder := json.NewEncoder(file) + encoder.Encode(state) + file.Close() + + old := path + ".old" + os.Rename(path, old) + os.Rename(tmp, path) +} -- GitLab