2015-05-30 19:44:18 +02:00
|
|
|
// +build go1.3,!plan9,!solaris
|
Reload authenticated-emails-file upon update
This change extracts the UserMap class from NewValidator() so that its
LoadAuthenticatedEmailsFile() method can be called concurrently. This method
is called by a goroutine containing a fsnotify.Watcher watching the
authenticated emails file.
Watching isn't forever aborted when the authenticated emails file disappears.
The goroutine will call os.Stat() up to twenty times a second if the file is
persistently missing, but that's the pathological case, not the common one.
The common case is that some editors (including Vim) will perform a
rename-and-replace when updating a file, triggering fsnotify.Rename events,
and the file will temporarily disappear. This watcher goroutine handles that
case.
Also, on some platforms (notably Arch Linux), a remove will be preceded by a
fsnotify.Chmod, causing a race between the upcoming fsnotify.Remove and the
call to UserMap.LoadAuthenticatedEmailsFile(). Hence, we treat fsnotify.Chmod
the same as fsnotify.Remove and fsnotify.Rename. There's no significant
penalty to re-adding a file to the watcher.
Also contains the following small changes from the summary of commits below:
- Minor optimization of email domain search
- Fixed api_test.go on Windows
- Add deferred File.Close() calls where needed
- Log error and return if emails file doesn't parse
These are the original commits from #89 squashed into this one:
0c6f2b6 Refactor validator_test to prepare for more tests
e0c792b Add more test cases to validator_test
a9a9d93 Minor optimization of email domain search
b763ea5 Extract LoadAuthenticatedEmailsFile()
8cdaf7f Introduce synchronized UserMap type
1b84eef Add UserMap methods, locking
af15dcf Reload authenticated-emails-file upon update
6d95548 Make UserMap operations lock-free
Per:
- http://stackoverflow.com/questions/21447463/is-assigning-a-pointer-atomic-in-golang
- https://groups.google.com/forum/#!msg/golang-nuts/ueSvaEKgyLY/ZW_74IC4PekJ
75755d5 Fix tests on Windows
d0eab2e Ignore email file watcher Chmod events
0b9798b Fix watcher on Ubuntu 12.04
3a8251a WaitForReplacement() to retry emails file watch
a57fd29 Add deferred File.Close() calls where needed
Because correctness: Don't leak file handles anywhere, and prepare for
future panics and early returns.
52ed3fd Log error and return if emails file doesn't parse
40100d4 Add gopkg.in/fsnotify.v1 dependency to Godeps file
17dfbbc Avoid a race when Remove is preceded by Chmod
2015-05-10 01:31:38 +02:00
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"gopkg.in/fsnotify.v1"
|
|
|
|
)
|
|
|
|
|
2015-05-14 13:57:30 +02:00
|
|
|
func WaitForReplacement(filename string, op fsnotify.Op,
|
|
|
|
watcher *fsnotify.Watcher) {
|
Reload authenticated-emails-file upon update
This change extracts the UserMap class from NewValidator() so that its
LoadAuthenticatedEmailsFile() method can be called concurrently. This method
is called by a goroutine containing a fsnotify.Watcher watching the
authenticated emails file.
Watching isn't forever aborted when the authenticated emails file disappears.
The goroutine will call os.Stat() up to twenty times a second if the file is
persistently missing, but that's the pathological case, not the common one.
The common case is that some editors (including Vim) will perform a
rename-and-replace when updating a file, triggering fsnotify.Rename events,
and the file will temporarily disappear. This watcher goroutine handles that
case.
Also, on some platforms (notably Arch Linux), a remove will be preceded by a
fsnotify.Chmod, causing a race between the upcoming fsnotify.Remove and the
call to UserMap.LoadAuthenticatedEmailsFile(). Hence, we treat fsnotify.Chmod
the same as fsnotify.Remove and fsnotify.Rename. There's no significant
penalty to re-adding a file to the watcher.
Also contains the following small changes from the summary of commits below:
- Minor optimization of email domain search
- Fixed api_test.go on Windows
- Add deferred File.Close() calls where needed
- Log error and return if emails file doesn't parse
These are the original commits from #89 squashed into this one:
0c6f2b6 Refactor validator_test to prepare for more tests
e0c792b Add more test cases to validator_test
a9a9d93 Minor optimization of email domain search
b763ea5 Extract LoadAuthenticatedEmailsFile()
8cdaf7f Introduce synchronized UserMap type
1b84eef Add UserMap methods, locking
af15dcf Reload authenticated-emails-file upon update
6d95548 Make UserMap operations lock-free
Per:
- http://stackoverflow.com/questions/21447463/is-assigning-a-pointer-atomic-in-golang
- https://groups.google.com/forum/#!msg/golang-nuts/ueSvaEKgyLY/ZW_74IC4PekJ
75755d5 Fix tests on Windows
d0eab2e Ignore email file watcher Chmod events
0b9798b Fix watcher on Ubuntu 12.04
3a8251a WaitForReplacement() to retry emails file watch
a57fd29 Add deferred File.Close() calls where needed
Because correctness: Don't leak file handles anywhere, and prepare for
future panics and early returns.
52ed3fd Log error and return if emails file doesn't parse
40100d4 Add gopkg.in/fsnotify.v1 dependency to Godeps file
17dfbbc Avoid a race when Remove is preceded by Chmod
2015-05-10 01:31:38 +02:00
|
|
|
const sleep_interval = 50 * time.Millisecond
|
|
|
|
|
|
|
|
// Avoid a race when fsnofity.Remove is preceded by fsnotify.Chmod.
|
2015-05-14 13:57:30 +02:00
|
|
|
if op&fsnotify.Chmod != 0 {
|
Reload authenticated-emails-file upon update
This change extracts the UserMap class from NewValidator() so that its
LoadAuthenticatedEmailsFile() method can be called concurrently. This method
is called by a goroutine containing a fsnotify.Watcher watching the
authenticated emails file.
Watching isn't forever aborted when the authenticated emails file disappears.
The goroutine will call os.Stat() up to twenty times a second if the file is
persistently missing, but that's the pathological case, not the common one.
The common case is that some editors (including Vim) will perform a
rename-and-replace when updating a file, triggering fsnotify.Rename events,
and the file will temporarily disappear. This watcher goroutine handles that
case.
Also, on some platforms (notably Arch Linux), a remove will be preceded by a
fsnotify.Chmod, causing a race between the upcoming fsnotify.Remove and the
call to UserMap.LoadAuthenticatedEmailsFile(). Hence, we treat fsnotify.Chmod
the same as fsnotify.Remove and fsnotify.Rename. There's no significant
penalty to re-adding a file to the watcher.
Also contains the following small changes from the summary of commits below:
- Minor optimization of email domain search
- Fixed api_test.go on Windows
- Add deferred File.Close() calls where needed
- Log error and return if emails file doesn't parse
These are the original commits from #89 squashed into this one:
0c6f2b6 Refactor validator_test to prepare for more tests
e0c792b Add more test cases to validator_test
a9a9d93 Minor optimization of email domain search
b763ea5 Extract LoadAuthenticatedEmailsFile()
8cdaf7f Introduce synchronized UserMap type
1b84eef Add UserMap methods, locking
af15dcf Reload authenticated-emails-file upon update
6d95548 Make UserMap operations lock-free
Per:
- http://stackoverflow.com/questions/21447463/is-assigning-a-pointer-atomic-in-golang
- https://groups.google.com/forum/#!msg/golang-nuts/ueSvaEKgyLY/ZW_74IC4PekJ
75755d5 Fix tests on Windows
d0eab2e Ignore email file watcher Chmod events
0b9798b Fix watcher on Ubuntu 12.04
3a8251a WaitForReplacement() to retry emails file watch
a57fd29 Add deferred File.Close() calls where needed
Because correctness: Don't leak file handles anywhere, and prepare for
future panics and early returns.
52ed3fd Log error and return if emails file doesn't parse
40100d4 Add gopkg.in/fsnotify.v1 dependency to Godeps file
17dfbbc Avoid a race when Remove is preceded by Chmod
2015-05-10 01:31:38 +02:00
|
|
|
time.Sleep(sleep_interval)
|
|
|
|
}
|
|
|
|
for {
|
2015-05-14 13:57:30 +02:00
|
|
|
if _, err := os.Stat(filename); err == nil {
|
|
|
|
if err := watcher.Add(filename); err == nil {
|
|
|
|
log.Printf("watching resumed for %s", filename)
|
Reload authenticated-emails-file upon update
This change extracts the UserMap class from NewValidator() so that its
LoadAuthenticatedEmailsFile() method can be called concurrently. This method
is called by a goroutine containing a fsnotify.Watcher watching the
authenticated emails file.
Watching isn't forever aborted when the authenticated emails file disappears.
The goroutine will call os.Stat() up to twenty times a second if the file is
persistently missing, but that's the pathological case, not the common one.
The common case is that some editors (including Vim) will perform a
rename-and-replace when updating a file, triggering fsnotify.Rename events,
and the file will temporarily disappear. This watcher goroutine handles that
case.
Also, on some platforms (notably Arch Linux), a remove will be preceded by a
fsnotify.Chmod, causing a race between the upcoming fsnotify.Remove and the
call to UserMap.LoadAuthenticatedEmailsFile(). Hence, we treat fsnotify.Chmod
the same as fsnotify.Remove and fsnotify.Rename. There's no significant
penalty to re-adding a file to the watcher.
Also contains the following small changes from the summary of commits below:
- Minor optimization of email domain search
- Fixed api_test.go on Windows
- Add deferred File.Close() calls where needed
- Log error and return if emails file doesn't parse
These are the original commits from #89 squashed into this one:
0c6f2b6 Refactor validator_test to prepare for more tests
e0c792b Add more test cases to validator_test
a9a9d93 Minor optimization of email domain search
b763ea5 Extract LoadAuthenticatedEmailsFile()
8cdaf7f Introduce synchronized UserMap type
1b84eef Add UserMap methods, locking
af15dcf Reload authenticated-emails-file upon update
6d95548 Make UserMap operations lock-free
Per:
- http://stackoverflow.com/questions/21447463/is-assigning-a-pointer-atomic-in-golang
- https://groups.google.com/forum/#!msg/golang-nuts/ueSvaEKgyLY/ZW_74IC4PekJ
75755d5 Fix tests on Windows
d0eab2e Ignore email file watcher Chmod events
0b9798b Fix watcher on Ubuntu 12.04
3a8251a WaitForReplacement() to retry emails file watch
a57fd29 Add deferred File.Close() calls where needed
Because correctness: Don't leak file handles anywhere, and prepare for
future panics and early returns.
52ed3fd Log error and return if emails file doesn't parse
40100d4 Add gopkg.in/fsnotify.v1 dependency to Godeps file
17dfbbc Avoid a race when Remove is preceded by Chmod
2015-05-10 01:31:38 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
time.Sleep(sleep_interval)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-31 04:02:35 +02:00
|
|
|
func WatchForUpdates(filename string, done <-chan bool, action func()) {
|
Reload authenticated-emails-file upon update
This change extracts the UserMap class from NewValidator() so that its
LoadAuthenticatedEmailsFile() method can be called concurrently. This method
is called by a goroutine containing a fsnotify.Watcher watching the
authenticated emails file.
Watching isn't forever aborted when the authenticated emails file disappears.
The goroutine will call os.Stat() up to twenty times a second if the file is
persistently missing, but that's the pathological case, not the common one.
The common case is that some editors (including Vim) will perform a
rename-and-replace when updating a file, triggering fsnotify.Rename events,
and the file will temporarily disappear. This watcher goroutine handles that
case.
Also, on some platforms (notably Arch Linux), a remove will be preceded by a
fsnotify.Chmod, causing a race between the upcoming fsnotify.Remove and the
call to UserMap.LoadAuthenticatedEmailsFile(). Hence, we treat fsnotify.Chmod
the same as fsnotify.Remove and fsnotify.Rename. There's no significant
penalty to re-adding a file to the watcher.
Also contains the following small changes from the summary of commits below:
- Minor optimization of email domain search
- Fixed api_test.go on Windows
- Add deferred File.Close() calls where needed
- Log error and return if emails file doesn't parse
These are the original commits from #89 squashed into this one:
0c6f2b6 Refactor validator_test to prepare for more tests
e0c792b Add more test cases to validator_test
a9a9d93 Minor optimization of email domain search
b763ea5 Extract LoadAuthenticatedEmailsFile()
8cdaf7f Introduce synchronized UserMap type
1b84eef Add UserMap methods, locking
af15dcf Reload authenticated-emails-file upon update
6d95548 Make UserMap operations lock-free
Per:
- http://stackoverflow.com/questions/21447463/is-assigning-a-pointer-atomic-in-golang
- https://groups.google.com/forum/#!msg/golang-nuts/ueSvaEKgyLY/ZW_74IC4PekJ
75755d5 Fix tests on Windows
d0eab2e Ignore email file watcher Chmod events
0b9798b Fix watcher on Ubuntu 12.04
3a8251a WaitForReplacement() to retry emails file watch
a57fd29 Add deferred File.Close() calls where needed
Because correctness: Don't leak file handles anywhere, and prepare for
future panics and early returns.
52ed3fd Log error and return if emails file doesn't parse
40100d4 Add gopkg.in/fsnotify.v1 dependency to Godeps file
17dfbbc Avoid a race when Remove is preceded by Chmod
2015-05-10 01:31:38 +02:00
|
|
|
filename = filepath.Clean(filename)
|
|
|
|
watcher, err := fsnotify.NewWatcher()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal("failed to create watcher for ", filename, ": ", err)
|
|
|
|
}
|
|
|
|
go func() {
|
|
|
|
defer watcher.Close()
|
|
|
|
for {
|
|
|
|
select {
|
2015-05-13 23:30:19 +02:00
|
|
|
case _ = <-done:
|
2015-11-09 10:28:34 +02:00
|
|
|
log.Printf("Shutting down watcher for: %s", filename)
|
|
|
|
break
|
Reload authenticated-emails-file upon update
This change extracts the UserMap class from NewValidator() so that its
LoadAuthenticatedEmailsFile() method can be called concurrently. This method
is called by a goroutine containing a fsnotify.Watcher watching the
authenticated emails file.
Watching isn't forever aborted when the authenticated emails file disappears.
The goroutine will call os.Stat() up to twenty times a second if the file is
persistently missing, but that's the pathological case, not the common one.
The common case is that some editors (including Vim) will perform a
rename-and-replace when updating a file, triggering fsnotify.Rename events,
and the file will temporarily disappear. This watcher goroutine handles that
case.
Also, on some platforms (notably Arch Linux), a remove will be preceded by a
fsnotify.Chmod, causing a race between the upcoming fsnotify.Remove and the
call to UserMap.LoadAuthenticatedEmailsFile(). Hence, we treat fsnotify.Chmod
the same as fsnotify.Remove and fsnotify.Rename. There's no significant
penalty to re-adding a file to the watcher.
Also contains the following small changes from the summary of commits below:
- Minor optimization of email domain search
- Fixed api_test.go on Windows
- Add deferred File.Close() calls where needed
- Log error and return if emails file doesn't parse
These are the original commits from #89 squashed into this one:
0c6f2b6 Refactor validator_test to prepare for more tests
e0c792b Add more test cases to validator_test
a9a9d93 Minor optimization of email domain search
b763ea5 Extract LoadAuthenticatedEmailsFile()
8cdaf7f Introduce synchronized UserMap type
1b84eef Add UserMap methods, locking
af15dcf Reload authenticated-emails-file upon update
6d95548 Make UserMap operations lock-free
Per:
- http://stackoverflow.com/questions/21447463/is-assigning-a-pointer-atomic-in-golang
- https://groups.google.com/forum/#!msg/golang-nuts/ueSvaEKgyLY/ZW_74IC4PekJ
75755d5 Fix tests on Windows
d0eab2e Ignore email file watcher Chmod events
0b9798b Fix watcher on Ubuntu 12.04
3a8251a WaitForReplacement() to retry emails file watch
a57fd29 Add deferred File.Close() calls where needed
Because correctness: Don't leak file handles anywhere, and prepare for
future panics and early returns.
52ed3fd Log error and return if emails file doesn't parse
40100d4 Add gopkg.in/fsnotify.v1 dependency to Godeps file
17dfbbc Avoid a race when Remove is preceded by Chmod
2015-05-10 01:31:38 +02:00
|
|
|
case event := <-watcher.Events:
|
|
|
|
// On Arch Linux, it appears Chmod events precede Remove events,
|
|
|
|
// which causes a race between action() and the coming Remove event.
|
|
|
|
// If the Remove wins, the action() (which calls
|
|
|
|
// UserMap.LoadAuthenticatedEmailsFile()) crashes when the file
|
|
|
|
// can't be opened.
|
|
|
|
if event.Op&(fsnotify.Remove|fsnotify.Rename|fsnotify.Chmod) != 0 {
|
|
|
|
log.Printf("watching interrupted on event: %s", event)
|
2015-05-14 13:57:30 +02:00
|
|
|
watcher.Remove(filename)
|
|
|
|
WaitForReplacement(filename, event.Op, watcher)
|
Reload authenticated-emails-file upon update
This change extracts the UserMap class from NewValidator() so that its
LoadAuthenticatedEmailsFile() method can be called concurrently. This method
is called by a goroutine containing a fsnotify.Watcher watching the
authenticated emails file.
Watching isn't forever aborted when the authenticated emails file disappears.
The goroutine will call os.Stat() up to twenty times a second if the file is
persistently missing, but that's the pathological case, not the common one.
The common case is that some editors (including Vim) will perform a
rename-and-replace when updating a file, triggering fsnotify.Rename events,
and the file will temporarily disappear. This watcher goroutine handles that
case.
Also, on some platforms (notably Arch Linux), a remove will be preceded by a
fsnotify.Chmod, causing a race between the upcoming fsnotify.Remove and the
call to UserMap.LoadAuthenticatedEmailsFile(). Hence, we treat fsnotify.Chmod
the same as fsnotify.Remove and fsnotify.Rename. There's no significant
penalty to re-adding a file to the watcher.
Also contains the following small changes from the summary of commits below:
- Minor optimization of email domain search
- Fixed api_test.go on Windows
- Add deferred File.Close() calls where needed
- Log error and return if emails file doesn't parse
These are the original commits from #89 squashed into this one:
0c6f2b6 Refactor validator_test to prepare for more tests
e0c792b Add more test cases to validator_test
a9a9d93 Minor optimization of email domain search
b763ea5 Extract LoadAuthenticatedEmailsFile()
8cdaf7f Introduce synchronized UserMap type
1b84eef Add UserMap methods, locking
af15dcf Reload authenticated-emails-file upon update
6d95548 Make UserMap operations lock-free
Per:
- http://stackoverflow.com/questions/21447463/is-assigning-a-pointer-atomic-in-golang
- https://groups.google.com/forum/#!msg/golang-nuts/ueSvaEKgyLY/ZW_74IC4PekJ
75755d5 Fix tests on Windows
d0eab2e Ignore email file watcher Chmod events
0b9798b Fix watcher on Ubuntu 12.04
3a8251a WaitForReplacement() to retry emails file watch
a57fd29 Add deferred File.Close() calls where needed
Because correctness: Don't leak file handles anywhere, and prepare for
future panics and early returns.
52ed3fd Log error and return if emails file doesn't parse
40100d4 Add gopkg.in/fsnotify.v1 dependency to Godeps file
17dfbbc Avoid a race when Remove is preceded by Chmod
2015-05-10 01:31:38 +02:00
|
|
|
}
|
|
|
|
log.Printf("reloading after event: %s", event)
|
|
|
|
action()
|
|
|
|
case err := <-watcher.Errors:
|
|
|
|
log.Printf("error watching %s: %s", filename, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
if err = watcher.Add(filename); err != nil {
|
|
|
|
log.Fatal("failed to add ", filename, " to watcher: ", err)
|
|
|
|
}
|
2015-05-31 04:02:35 +02:00
|
|
|
log.Printf("watching %s for updates", filename)
|
Reload authenticated-emails-file upon update
This change extracts the UserMap class from NewValidator() so that its
LoadAuthenticatedEmailsFile() method can be called concurrently. This method
is called by a goroutine containing a fsnotify.Watcher watching the
authenticated emails file.
Watching isn't forever aborted when the authenticated emails file disappears.
The goroutine will call os.Stat() up to twenty times a second if the file is
persistently missing, but that's the pathological case, not the common one.
The common case is that some editors (including Vim) will perform a
rename-and-replace when updating a file, triggering fsnotify.Rename events,
and the file will temporarily disappear. This watcher goroutine handles that
case.
Also, on some platforms (notably Arch Linux), a remove will be preceded by a
fsnotify.Chmod, causing a race between the upcoming fsnotify.Remove and the
call to UserMap.LoadAuthenticatedEmailsFile(). Hence, we treat fsnotify.Chmod
the same as fsnotify.Remove and fsnotify.Rename. There's no significant
penalty to re-adding a file to the watcher.
Also contains the following small changes from the summary of commits below:
- Minor optimization of email domain search
- Fixed api_test.go on Windows
- Add deferred File.Close() calls where needed
- Log error and return if emails file doesn't parse
These are the original commits from #89 squashed into this one:
0c6f2b6 Refactor validator_test to prepare for more tests
e0c792b Add more test cases to validator_test
a9a9d93 Minor optimization of email domain search
b763ea5 Extract LoadAuthenticatedEmailsFile()
8cdaf7f Introduce synchronized UserMap type
1b84eef Add UserMap methods, locking
af15dcf Reload authenticated-emails-file upon update
6d95548 Make UserMap operations lock-free
Per:
- http://stackoverflow.com/questions/21447463/is-assigning-a-pointer-atomic-in-golang
- https://groups.google.com/forum/#!msg/golang-nuts/ueSvaEKgyLY/ZW_74IC4PekJ
75755d5 Fix tests on Windows
d0eab2e Ignore email file watcher Chmod events
0b9798b Fix watcher on Ubuntu 12.04
3a8251a WaitForReplacement() to retry emails file watch
a57fd29 Add deferred File.Close() calls where needed
Because correctness: Don't leak file handles anywhere, and prepare for
future panics and early returns.
52ed3fd Log error and return if emails file doesn't parse
40100d4 Add gopkg.in/fsnotify.v1 dependency to Godeps file
17dfbbc Avoid a race when Remove is preceded by Chmod
2015-05-10 01:31:38 +02:00
|
|
|
}
|