kleinCommand/services/baseService.go

88 lines
1.7 KiB
Go
Raw Permalink Normal View History

2025-07-20 16:22:46 +02:00
package services
import (
"bufio"
"github.com/DariusKlein/kleinCommand/common"
"log"
"net"
"os"
"sync"
"time"
)
2025-07-20 18:46:55 +02:00
func BaseService(socketPath string, logic func(string, net.Conn)) {
2025-07-20 16:22:46 +02:00
// Remove socket path on os.Interrupt and syscall.SIGTERM
common.CatchInterrupt(func() {
os.Remove(socketPath)
})
// Check if socket exists
if common.FileExists(socketPath) {
log.Fatal("Socket file exists.")
}
// Create the UNIX socket listener.
listener, err := net.Listen("unix", socketPath)
if err != nil {
log.Fatalf("Failed to listen on socket: %v", err)
}
log.Println("Service started, listening on", socketPath)
shutdownChan := make(chan struct{})
var once sync.Once
closeOnce := func() {
once.Do(func() {
close(shutdownChan)
})
}
go func() {
for {
conn, err := listener.Accept()
if err != nil {
log.Printf("Accept error: %v", err)
closeOnce()
return
}
go handleConnection(conn, logic, listener)
}
}()
go func() {
ticker := time.NewTicker(5 * time.Second) // Check every 5 seconds
defer ticker.Stop()
for {
select {
case <-ticker.C:
if _, err := os.Stat(socketPath); os.IsNotExist(err) {
log.Println("Socket file deleted externally, signaling shutdown.")
closeOnce()
return
}
case <-shutdownChan:
return
}
}
}()
<-shutdownChan
common.DeleteSelf()
}
2025-07-20 18:46:55 +02:00
func handleConnection(conn net.Conn, logic func(string, net.Conn), listener net.Listener) {
2025-07-20 16:22:46 +02:00
defer conn.Close()
scanner := bufio.NewScanner(conn)
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
input := scanner.Text()
if input == "shutdown" {
log.Println("Shutdown command received, exiting.")
listener.Close()
} else {
2025-07-20 18:46:55 +02:00
logic(input, conn)
2025-07-20 16:22:46 +02:00
}
}
}