2025-10-31 14:26:17 +01:00

222 lines
4.2 KiB
Go

package main
import (
"embed"
"fmt"
"ld/eventbus"
"ld/interval"
"ld/server"
"ld/sqlite"
"log"
"os"
"os/signal"
"path/filepath"
"strings"
"syscall"
)
const (
exitCodeErr = 1
exitCodeInterrupt = 2
)
var AppRoot = "./" // path for supporting files that sit in app root folder in production
//go:embed frontend/*
var frontend embed.FS
//go:embed embed
var embedded embed.FS
// main specific variables
var ExecutableName string
func main() {
fmt.Println("Here")
err := run()
if err != nil {
os.Exit(exitCodeErr)
}
ExecutableName, err = getExecutableName()
if err != nil {
os.Exit(exitCodeErr)
}
// readCrew()
// readMessages()
ebus := eventbus.NewEventBus()
interval.SetInterval(func() {
fmt.Println("------------------")
}, 10)
interval.SetInterval(func() {
ebus.Publish("foo:baz", eventbus.Data{"value": "Hallo Welt"})
}, 100)
runEventbus(ebus)
run()
}
func runEventbus(ebus *eventbus.EventBus) {
// Create a new instance
eventChannel := eventbus.NewEventChannel()
// Subscribe to "foo:baz" - or use a wildcard like "foo:*"
ebus.SubscribeChannel("foo:baz", eventChannel)
ebus.SubscribeChannel("pups-klo", eventChannel)
ebus.SubscribeChannel("ömme*", eventChannel)
eventChannelTopic := ebus.Subscribe("ömmels")
// Subscribe with existing channel use
// eventbus.SubscribeChannel("foo:*", eventChannel)
// Wait for the incoming event on the channel
go func() {
for evt := range eventChannel {
fmt.Println("FIRST", evt.Topic, evt.Data)
evt.Done()
}
}()
go func() {
for evt := range eventChannel {
fmt.Println("SECOND", evt.Topic, evt.Data)
evt.Done()
}
}()
go func() {
for evt := range eventChannelTopic {
fmt.Println("ÖMMELS", evt.Topic, evt.Data)
evt.Done()
}
}()
for i := 0; i < 1000; i++ {
ebus.Publish("foo:baz", eventbus.Data{"value": i})
ebus.Publish("pups-klo", eventbus.Data{"value": i})
ebus.Publish("pups-klo", eventbus.Data{"value": i})
ebus.Publish("ömmels", eventbus.Data{"value": i})
ebus.Publish("ömmels", eventbus.Data{"value": i * 10})
ebus.Publish("ömmels", eventbus.Data{"value": i * 100})
}
}
func run() error {
// setting up logging to file
logFileName := AppRoot + ExecutableName + ".log"
logFile, err := os.OpenFile(logFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Printf("error opening file: %v", err)
os.Exit(exitCodeErr)
}
defer logFile.Close()
log.SetOutput(logFile)
stateDB, err := createStateDB(true)
if err != nil {
log.Fatalf("Failed to create internal StateDB: %v", err)
}
// setting up the server
server, err := server.New(
logFileName,
stateDB,
embedded,
)
if err != nil {
log.Fatalf("server-app not created - error: %v", err)
}
// tasks.SetupTasks(server)
err = server.Start()
if err != nil {
fmt.Printf("server not started - error: %v \n", err)
log.Fatalf("server not started - error: %v", err)
}
readCrew(server)
readMessages(server)
// return nil
// listen for os shutdown events, report them into log file and exit application
chanOS := make(chan os.Signal, 2)
signal.Notify(chanOS, os.Interrupt, syscall.SIGTERM)
go func() {
<-chanOS
log.Println("shutting down request signal received")
server.Close()
os.Exit(exitCodeInterrupt)
}()
// setting up the routes, hooking up API endpoints with backend functions
// routes.SetupRoutes(server)
return nil
}
// some internal functions
func getExecutableName() (string, error) {
name, err := os.Executable()
if err != nil {
return "", err
}
name = filepath.Base(name)
return strings.TrimSuffix(name, filepath.Ext(name)), nil
}
func createStateDB(StateDBDelete bool) (*sqlite.Database, error) {
// fileName := fmt.Sprintf("state-%s.db", ulid.Make())
fileName := "state.db"
if StateDBDelete {
_, err := os.Stat(fileName)
if err == nil {
err := os.Remove(fileName)
if err != nil {
log.Fatal("error deleting statedb-file:", err)
}
}
}
db, err := sqlite.New(fileName)
if err != nil {
return nil, err
}
err = db.Open()
if err != nil {
return nil, err
}
query, err := embedded.ReadFile("embed/create_state_db.sql")
if err != nil {
return nil, err
}
_, err = db.DB().Exec(string(query))
if err != nil {
return nil, err
}
return db, nil
}