155 lines
2.6 KiB
Go
155 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
"time"
|
|
|
|
"git.abbiamoundominio.org/blallo/broadcast"
|
|
"git.sr.ht/~blallo/logz/interface"
|
|
"git.sr.ht/~blallo/logz/zlog"
|
|
)
|
|
|
|
var (
|
|
debug = flag.Bool("debug", false, "Enable debug logging")
|
|
)
|
|
|
|
func main() {
|
|
logger := zlog.NewConsoleLogger()
|
|
|
|
flag.Parse()
|
|
|
|
if flag.NArg() < 1 {
|
|
logger.Err(map[string]any{
|
|
"msg": "Wrong number of arguments",
|
|
})
|
|
os.Exit(1)
|
|
}
|
|
|
|
if *debug {
|
|
logger.SetLevel(logz.LogDebug)
|
|
}
|
|
|
|
prog := flag.Arg(0)
|
|
cmdLine := flag.Args()[1:]
|
|
|
|
radio, err := broadcast.NewRadio(logger, prog, cmdLine...)
|
|
if err != nil {
|
|
logger.Err(map[string]any{
|
|
"msg": "Failed to start",
|
|
"err": err,
|
|
})
|
|
os.Exit(2)
|
|
}
|
|
|
|
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
|
|
defer cancel()
|
|
|
|
start := make(chan os.Signal)
|
|
stop := make(chan os.Signal)
|
|
status := make(chan os.Signal)
|
|
|
|
signal.Notify(start, syscall.SIGUSR1)
|
|
signal.Notify(stop, syscall.SIGTSTP)
|
|
signal.Notify(status, syscall.SIGUSR2)
|
|
|
|
go func() {
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case <-start:
|
|
resp := <-radio.Start()
|
|
if resp != nil {
|
|
logger.Warn(map[string]any{
|
|
"msg": "Failed to start",
|
|
"err": resp.(error).Error(),
|
|
})
|
|
} else {
|
|
logger.Info(map[string]any{
|
|
"msg": "Started",
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
|
|
go func() {
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case <-stop:
|
|
resp := <-radio.Stop()
|
|
if resp != nil {
|
|
logger.Warn(map[string]any{
|
|
"msg": "Failed to stop",
|
|
"err": resp.(error).Error(),
|
|
})
|
|
} else {
|
|
logger.Info(map[string]any{
|
|
"msg": "Stopped",
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
|
|
go func() {
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case <-status:
|
|
resp := <-radio.Status()
|
|
for i, line := range resp.([]string) {
|
|
logger.Info(map[string]any{
|
|
"msg": line,
|
|
"lineNum": i,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
|
|
go func() {
|
|
resp, err := withTimeout(ctx, radio.Start())
|
|
if err != nil {
|
|
logger.Err(map[string]any{
|
|
"msg": "Cannot start",
|
|
"err": err.Error(),
|
|
})
|
|
} else {
|
|
if resp != nil {
|
|
logger.Info(map[string]any{
|
|
"msg": "Started",
|
|
"resp": resp.(error).Error(),
|
|
})
|
|
}
|
|
}
|
|
}()
|
|
|
|
if err := radio.Run(ctx); err != nil {
|
|
logger.Err(map[string]any{
|
|
"msg": "Execution failed",
|
|
"err": err.Error(),
|
|
})
|
|
os.Exit(2)
|
|
}
|
|
}
|
|
|
|
func withTimeout[T any](ctx context.Context, respCh <-chan T) (zero T, err error) {
|
|
shortCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
|
defer cancel()
|
|
|
|
select {
|
|
case <-shortCtx.Done():
|
|
return zero, shortCtx.Err()
|
|
case resp := <-respCh:
|
|
return resp, nil
|
|
}
|
|
}
|