prevent multiple instances in same namespace
This commit is contained in:
parent
c2f17beff5
commit
77821a7d01
|
|
@ -34,6 +34,7 @@ import (
|
|||
"denote/internal/disk"
|
||||
"denote/pkg/encoding/results"
|
||||
"denote/pkg/metadata"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
|
|
@ -41,6 +42,7 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"9fans.net/go/plan9"
|
||||
|
|
@ -165,14 +167,36 @@ func StartServer(initialData metadata.Results, denoteDir string, callbacks Callb
|
|||
|
||||
sockPath := ns + "/denote"
|
||||
|
||||
// Remove old socket if it exists
|
||||
os.Remove(sockPath)
|
||||
// Try to create Unix domain socket listener
|
||||
// Use stale socket detection like acme (see /usr/local/plan9/src/lib9/announce.c)
|
||||
var listener net.Listener
|
||||
var err error
|
||||
for attempts := 0; attempts < 2; attempts++ {
|
||||
listener, err = net.Listen("unix", sockPath)
|
||||
if err == nil {
|
||||
break // Successfully bound to socket
|
||||
}
|
||||
|
||||
// Create Unix domain socket listener
|
||||
listener, err := net.Listen("unix", sockPath)
|
||||
if err != nil {
|
||||
// Check if error is "address already in use"
|
||||
if errors.Is(err, syscall.EADDRINUSE) {
|
||||
// Try to connect to see if socket is live or stale
|
||||
conn, dialErr := net.Dial("unix", sockPath)
|
||||
if dialErr == nil {
|
||||
// Connection succeeded - another instance is running
|
||||
conn.Close()
|
||||
return fmt.Errorf("Denote already running in this namespace")
|
||||
}
|
||||
// Connection failed - socket is stale, remove it and retry
|
||||
os.Remove(sockPath)
|
||||
continue
|
||||
}
|
||||
|
||||
// Some other error
|
||||
return fmt.Errorf("failed to listen on socket: %w", err)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to listen on socket after cleanup: %w", err)
|
||||
}
|
||||
|
||||
// Start accepting connections in background
|
||||
go srv.acceptLoop(listener)
|
||||
|
|
|
|||
17
main.go
17
main.go
|
|
@ -243,14 +243,25 @@ func main() {
|
|||
|
||||
// 9p server startup with pre-loaded data and callbacks
|
||||
if err := p9server.StartServer(notes, denoteDir, callbacks); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "warning: failed to start fileserver: %v\n", err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// start acme log watcher
|
||||
go disk.WatchAcmeLog()
|
||||
|
||||
// open window
|
||||
if w = acme.Show(wname); w == nil {
|
||||
// open window - look for existing /Denote/ window across all processes
|
||||
if wins, err := acme.Windows(); err == nil {
|
||||
for _, winInfo := range wins {
|
||||
if winInfo.Name == wname {
|
||||
// Found existing window, open it
|
||||
if w, err = acme.Open(winInfo.ID, nil); err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If no existing window found, create new one
|
||||
if w == nil {
|
||||
if w, err = acme.New(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue