created base service

This commit is contained in:
Darius klein 2025-07-20 16:22:46 +02:00
parent 8be8069ec0
commit f54c2a1b70
8 changed files with 97 additions and 53 deletions

87
services/baseService.go Normal file
View File

@ -0,0 +1,87 @@
package services
import (
"bufio"
"github.com/DariusKlein/kleinCommand/common"
"log"
"net"
"os"
"sync"
"time"
)
func BaseService(socketPath string, logic func(string)) {
// 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()
}
func handleConnection(conn net.Conn, logic func(string), listener net.Listener) {
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 {
logic(input)
}
}
}

BIN
services/binaries/exampleService Executable file

Binary file not shown.

Binary file not shown.

View File

@ -1,60 +1,17 @@
package main package main
import ( import (
"bufio"
"github.com/DariusKlein/kleinCommand/common" "github.com/DariusKlein/kleinCommand/common"
"log" "github.com/DariusKlein/kleinCommand/services"
"net"
"os"
) )
var socketPath = common.ExampleServiceSocketPath var socketPath = common.ExampleServiceSocketPath
func main() { func main() {
common.CatchInterrupt(func() { services.BaseService(socketPath, func(command string) {
os.Remove(socketPath) switch command {
case "example\n":
}
}) })
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)
}
defer listener.Close()
log.Println("Service started, listening on", socketPath)
go func() {
conn, err := listener.Accept()
if err != nil {
log.Printf("Accept error: %v", err)
return
}
defer conn.Close()
reader := bufio.NewReader(conn)
command, err := reader.ReadString('\n')
if err != nil {
log.Printf("Read error: %v", err)
return
}
if command == "shutdown\n" {
log.Println("Shutdown command received, exiting.")
// This will cause the listener.Accept() to unblock and the program to exit.
listener.Close()
}
}()
for {
if _, err := os.Stat(socketPath); os.IsNotExist(err) {
break
}
}
common.DeleteSelf()
} }

Binary file not shown.

Binary file not shown.

View File

@ -2,7 +2,7 @@
package services package services
//go:generate go build ./example //go:generate go build -o binaries/ ./example
import ( import (
_ "embed" _ "embed"
@ -11,7 +11,7 @@ import (
"syscall" "syscall"
) )
//go:embed exampleService //go:embed binaries/exampleService
var exampleService []byte var exampleService []byte
func runService(name string, file []byte) error { func runService(name string, file []byte) error {

View File

@ -2,7 +2,7 @@
package services package services
//go:generate go build ./example //go:generate go build -o binaries/ ./example
import ( import (
_ "embed" _ "embed"
@ -11,7 +11,7 @@ import (
"syscall" "syscall"
) )
//go:embed exampleService.exe //go:embed binaries/exampleService.exe
var exampleService []byte var exampleService []byte
func runService(name string, file []byte) error { func runService(name string, file []byte) error {