Adds web endpoint

This commit is contained in:
Miguel de la Cruz 2023-07-11 12:37:56 +02:00
parent 045c8760fe
commit 0bd05b6efe
5 changed files with 121 additions and 4 deletions

View file

@ -47,8 +47,16 @@ func main() {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
srv.Start()
if err := srv.Start(); err != nil {
fmt.Fprintf(os.Stderr, "ERROR: cannot start server: %s\n", err)
os.Exit(1)
}
s := <-c
srv.Logger.Info("received signal, stopping", "signal", s)
srv.Stop()
if err := srv.Stop(); err != nil {
fmt.Fprintf(os.Stderr, "ERROR: cannot stop server: %s\n", err)
os.Exit(1)
}
}

View file

@ -1,4 +1,7 @@
---
web:
port: 8080
birthdays:
file: birthdays.csv
template: ./birthday_message.tmpl

View file

@ -19,6 +19,7 @@ var (
type Config struct {
Birthdays *BirthdaysConfig `yaml:"birthdays"`
Logger *LoggerConfig `yaml:"logger"`
Web *WebConfig `yaml:"web"`
TelegramNotifications *TelegramNotificationsConfig `yaml:"telegram_notifications"`
}
@ -31,6 +32,10 @@ func (c *Config) IsValid() error {
return fmt.Errorf("invalid logger config: %w", err)
}
if err := c.Web.IsValid(); err != nil {
return fmt.Errorf("invalid web config: %w", err)
}
if c.TelegramNotifications != nil {
if err := c.TelegramNotifications.IsValid(); err != nil {
return fmt.Errorf("invalid telegram notifications config: %w", err)
@ -53,6 +58,12 @@ func (c *Config) SetDefaults() {
c.Logger.SetDefaults()
if c.Web == nil {
c.Web = &WebConfig{}
}
c.Web.SetDefaults()
if c.TelegramNotifications != nil {
c.TelegramNotifications.SetDefaults()
}
@ -99,6 +110,20 @@ func (lc *LoggerConfig) IsValid() error {
return nil
}
type WebConfig struct {
Port int `yaml:"port"`
}
func (wc *WebConfig) SetDefaults() {
if wc.Port == 0 {
wc.Port = 8080
}
}
func (wc *WebConfig) IsValid() error {
return nil
}
type TelegramNotificationsConfig struct {
BotToken string `yaml:"bot_token"`
ChannelID string `yaml:"channel_id"`

View file

@ -22,6 +22,7 @@ var (
type Server struct {
Logger *log.Logger
Config *model.Config
WebServer *WebServer
workers []Worker
birthdays []*model.Birthday
notificationServices []notification.NotificationService
@ -107,23 +108,45 @@ func New(options ...Option) (*Server, error) {
}
}
if srv.WebServer == nil {
srv.Logger.Debug("creating web server")
srv.WebServer = NewWebServer(srv)
}
return srv, nil
}
func (s *Server) Start() {
func (s *Server) Start() error {
s.Logger.Info("starting server")
if err := s.WebServer.Start(); err != nil {
return fmt.Errorf("cannot start web server: %w", err)
}
for _, worker := range s.workers {
worker.Start()
}
s.Logger.Debug("server started", "workers", len(s.workers))
return nil
}
func (s *Server) Stop() {
func (s *Server) Stop() error {
s.Logger.Info("stopping server")
if err := s.WebServer.Stop(); err != nil {
return fmt.Errorf("cannot stop web server: %w", err)
}
for _, worker := range s.workers {
worker.Stop()
}
s.Logger.Debug("server stopped", "workers", len(s.workers))
return nil
}
func (s *Server) Notify(birthday *model.Birthday) error {

58
server/web.go Normal file
View file

@ -0,0 +1,58 @@
package server
import (
"errors"
"fmt"
"net/http"
"github.com/charmbracelet/log"
)
type WebServer struct {
server *Server
logger *log.Logger
httpServer *http.Server
}
func NewWebServer(server *Server) *WebServer {
ws := &WebServer{
server: server,
logger: server.Logger,
httpServer: &http.Server{
Addr: fmt.Sprintf(":%d", server.Config.Web.Port),
},
}
mux := http.NewServeMux()
mux.HandleFunc("/health", ws.healthHandler)
ws.httpServer.Handler = mux
return ws
}
func (ws *WebServer) Start() error {
ws.logger.Debug("starting web server")
go func() {
if err := ws.httpServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
ws.logger.Fatal("cannot start web server", "error", err)
}
}()
return nil
}
func (ws *WebServer) Stop() error {
ws.logger.Debug("stopping web server")
if err := ws.httpServer.Close(); err != nil {
return fmt.Errorf("cannot stop web server: %w", err)
}
return nil
}
func (ws *WebServer) healthHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "OK")
}