mirror of
https://github.com/jeremyd/ergo.git
synced 2026-04-26 15:40:00 -07:00
optionally protect against multiple starts with flock (#1873)
* optionally protect against multiple starts with flock Fixes #1823 * use traditional .lock extension * move config key to top level
This commit is contained in:
committed by
GitHub
parent
e112a78b9b
commit
ed75533cb1
@@ -616,6 +616,8 @@ type Config struct {
|
||||
|
||||
languageManager *languages.Manager
|
||||
|
||||
LockFile string `yaml:"lock-file"`
|
||||
|
||||
Datastore struct {
|
||||
Path string
|
||||
AutoUpgrade bool
|
||||
|
||||
24
irc/flock/flock.go
Normal file
24
irc/flock/flock.go
Normal file
@@ -0,0 +1,24 @@
|
||||
//go:build !plan9
|
||||
|
||||
package flock
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/gofrs/flock"
|
||||
)
|
||||
|
||||
var (
|
||||
CouldntAcquire = errors.New("Couldn't acquire flock (is another Ergo running?)")
|
||||
)
|
||||
|
||||
func TryAcquireFlock(path string) (fl Flocker, err error) {
|
||||
f := flock.New(path)
|
||||
success, err := f.TryLock()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !success {
|
||||
return nil, CouldntAcquire
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
14
irc/flock/flock_iface.go
Normal file
14
irc/flock/flock_iface.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package flock
|
||||
|
||||
// documentation for github.com/gofrs/flock incorrectly claims that
|
||||
// Flock implements sync.Locker; it does not because the Unlock method
|
||||
// has a return type (err).
|
||||
type Flocker interface {
|
||||
Unlock() error
|
||||
}
|
||||
|
||||
type noopFlocker struct{}
|
||||
|
||||
func (n *noopFlocker) Unlock() error {
|
||||
return nil
|
||||
}
|
||||
7
irc/flock/flock_plan9.go
Normal file
7
irc/flock/flock_plan9.go
Normal file
@@ -0,0 +1,7 @@
|
||||
//go:build plan9
|
||||
|
||||
package flock
|
||||
|
||||
func TryAcquireFlock(path string) (fl Flocker, err error) {
|
||||
return &noopFlocker{}, nil
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"github.com/ergochat/ergo/irc/caps"
|
||||
"github.com/ergochat/ergo/irc/connection_limits"
|
||||
"github.com/ergochat/ergo/irc/flatip"
|
||||
"github.com/ergochat/ergo/irc/flock"
|
||||
"github.com/ergochat/ergo/irc/history"
|
||||
"github.com/ergochat/ergo/irc/logger"
|
||||
"github.com/ergochat/ergo/irc/modes"
|
||||
@@ -88,6 +89,7 @@ type Server struct {
|
||||
whoWas WhoWasList
|
||||
stats Stats
|
||||
semaphores ServerSemaphores
|
||||
flock flock.Flocker
|
||||
defcon uint32
|
||||
}
|
||||
|
||||
@@ -585,6 +587,19 @@ func (server *Server) applyConfig(config *Config) (err error) {
|
||||
|
||||
server.logger.Info("server", "Using config file", server.configFilename)
|
||||
|
||||
if initial {
|
||||
if config.LockFile != "" {
|
||||
server.flock, err = flock.TryAcquireFlock(config.LockFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to acquire flock on %s: %w",
|
||||
config.LockFile, err)
|
||||
}
|
||||
}
|
||||
// the lock is never released until quit; we need to save a pointer
|
||||
// to the (*flock.Flock) object so it doesn't get GC'ed, which would
|
||||
// close the file and surrender the lock
|
||||
}
|
||||
|
||||
// first, reload config sections for functionality implemented in subpackages:
|
||||
wasLoggingRawIO := !initial && server.logger.IsLoggingRawIO()
|
||||
err = server.logger.ApplyConfig(config.Logging)
|
||||
|
||||
Reference in New Issue
Block a user