package main
import (
"context"
"essentials/controllers"
"essentials/libraries/config"
"essentials/libraries/database"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
_ "github.com/go-sql-driver/mysql"
)
func main() {
if _, ok := os.LookupEnv("APP_ENV"); !ok {
config.Setup(".env")
}
// =========================================================================
// App Starting
log.Printf("main : Started")
defer log.Println("main : Completed")
// =========================================================================
// Start Database
db, err := database.Open()
if err != nil {
log.Fatalf("error: connecting to db: %s", err)
}
defer db.Close()
// Create variable service with pattern dependency injection.
// Inject koneksion db to type of Users
service := controllers.Users{Db: db}
// parameter server
server := http.Server{
Addr: os.Getenv("APP_PORT"),
Handler: http.HandlerFunc(service.List),
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
}
serverErrors := make(chan error, 1)
// mulai listening server
go func() {
log.Println("server listening on", server.Addr)
serverErrors <- server.ListenAndServe()
}()
// Membuat channel untuk mendengarkan sinyal interupsi/terminate dari OS.
// Menggunakan channel buffered karena paket signal membutuhkannya.
shutdown := make(chan os.Signal, 1)
signal.Notify(shutdown, os.Interrupt, syscall.SIGTERM)
// Mengontrol penerimaan data dari channel,
// jika ada error saat listenAndServe server maupun ada sinyal shutdown yang diterima
select {
case err := <-serverErrors:
log.Fatalf("error: listening and serving: %s", err)
case <-shutdown:
log.Println("caught signal, shutting down")
// Jika ada shutdown, meminta tambahan waktu 5 detik untuk menyelesaikan proses yang sedang berjalan.
const timeout = 5 * time.Second
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
log.Printf("error: gracefully shutting down server: %s", err)
if err := server.Close(); err != nil {
log.Printf("error: closing server: %s", err)
}
}
}
log.Println("done")
}