narasiahli-be/config/webserver/webserver.config.go

186 lines
5.1 KiB
Go

package webserver
import (
"context"
"flag"
"fmt"
"narasi-ahli-be/app/database"
"narasi-ahli-be/app/database/seeds"
md "narasi-ahli-be/app/middleware"
articlesService "narasi-ahli-be/app/module/articles/service"
"narasi-ahli-be/app/router"
"narasi-ahli-be/config/config"
"narasi-ahli-be/utils/response"
"os"
"runtime"
"strings"
"time"
"github.com/go-co-op/gocron"
"github.com/gofiber/fiber/v2"
futils "github.com/gofiber/fiber/v2/utils"
"github.com/rs/zerolog"
"go.uber.org/fx"
)
// NewFiber : initialize the webserver
func NewFiber(cfg *config.Config) *fiber.App {
// setup
app := fiber.New(fiber.Config{
ServerHeader: cfg.App.Name,
AppName: cfg.App.Name,
Prefork: cfg.App.Prefork,
ErrorHandler: response.ErrorHandler,
IdleTimeout: cfg.App.IdleTimeout * time.Second,
EnablePrintRoutes: cfg.App.PrintRoutes,
BodyLimit: cfg.App.BodyLimit,
DisableStartupMessage: true,
ReadBufferSize: 8192,
})
// pass production config to check it
response.IsProduction = cfg.App.Production
return app
}
// Start : function to start webserver
func Start(lifecycle fx.Lifecycle, cfg *config.Config, fiber *fiber.App, router *router.Router, middlewares *md.Middleware, db *database.Database, log zerolog.Logger) {
lifecycle.Append(
fx.Hook{
OnStart: func(ctx context.Context) error {
// Connect database
db.ConnectDatabase()
// Register middlewares
middlewares.Register(db)
// Register routes
router.Register()
// Custom Startup Messages
host, port := config.ParseAddress(cfg.App.Port)
if host == "" {
if fiber.Config().Network == "tcp6" {
host = "[::1]"
} else {
host = "0.0.0.0"
}
}
// ASCII Art
ascii, err := os.ReadFile("./storage/ascii_art.txt")
if err != nil {
log.Debug().Err(err).Msg("An unknown error occurred when to print ASCII art!")
}
for _, line := range strings.Split(futils.UnsafeString(ascii), "\n") {
log.Info().Msg(line)
}
// Information message
log.Info().Msg(fiber.Config().AppName + " is running at the moment!")
// Debug informations
if !cfg.App.Production {
prefork := "Enabled"
procs := runtime.GOMAXPROCS(0)
if !cfg.App.Prefork {
procs = 1
prefork = "Disabled"
}
log.Debug().Msgf("Version: %s", "-")
log.Debug().Msgf("Host: %s", host)
log.Debug().Msgf("Port: %s", port)
log.Debug().Msgf("Prefork: %s", prefork)
log.Debug().Msgf("Handlers: %d", fiber.HandlersCount())
log.Debug().Msgf("Processes: %d", procs)
log.Debug().Msgf("PID: %d", os.Getpid())
}
// Listen the app (with TLS Support)
//if cfg.App.TLS.Enable {
// log.Debug().Msg("TLS support was enabled.")
//
// if err := fiber.ListenTLS(cfg.App.Port, cfg.App.TLS.CertFile, cfg.App.TLS.KeyFile); err != nil {
// log.Error().Err(err).Msg("An unknown error occurred when to run server!")
// }
//}
go func() {
if err := fiber.Listen(cfg.App.Port); err != nil {
log.Error().Err(err).Msg("An unknown error occurred when to run server!")
}
}()
migrateFlag := flag.Bool("migrate", db.Cfg.DB.Postgres.Migrate, "migrate the database")
seedFlag := flag.Bool("seed", db.Cfg.DB.Postgres.Seed, "seed the database")
flag.Parse()
// read flag -migrate to migrate the database
if *migrateFlag {
db.MigrateModels()
}
// read flag -seed to seed the database
if *seedFlag {
// init seed models
masterStatusSeeder := seeds.MasterStatusesSeeder{}
masterApprovalStatusSeeder := seeds.MasterApprovalStatusesSeeder{}
activityLogsSeeder := seeds.ActivityLogsSeeder{}
allSeeders := []database.Seeder{masterStatusSeeder, masterApprovalStatusSeeder, activityLogsSeeder}
db.SeedModels(allSeeders)
}
return nil
},
OnStop: func(ctx context.Context) error {
log.Info().Msg("Shutting down the app...")
if err := fiber.Shutdown(); err != nil {
log.Panic().Err(err).Msg("")
}
log.Info().Msg("Running cleanup tasks...")
log.Info().Msg("1- Shutdown the database")
db.ShutdownDatabase()
log.Info().Msgf("%s was successful shutdown.", cfg.App.Name)
log.Info().Msg("\u001b[96msee you again👋\u001b[0m")
return nil
},
},
)
}
func RunScheduling(lifecycle fx.Lifecycle, articleService articlesService.ArticlesService) *gocron.Scheduler {
scheduler := gocron.NewScheduler(time.UTC)
// Tambahkan tugas yang berjalan setiap 10 detik
// scheduler.Every(1).Minutes().SingletonMode().Do(func() {
// fmt.Println("Run Scheduler", time.Now())
// err := articleService.ExecuteScheduling()
// if err != nil {
// fmt.Println("Scheduler Got An Error", time.Now())
// }
// })
// Menambahkan lifecycle hooks di Fx
lifecycle.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
fmt.Println("Memulai scheduler...")
scheduler.StartAsync() // Mulai scheduler saat aplikasi dimulai
return nil
},
OnStop: func(ctx context.Context) error {
fmt.Println("Menghentikan scheduler...")
scheduler.Stop() // Hentikan scheduler saat aplikasi dihentikan
return nil
},
})
return scheduler
}