initial commit
This commit is contained in:
125
cmd/api/main.go
Normal file
125
cmd/api/main.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"git.kirlllll.ru/volontery/backend/internal/api"
|
||||
"git.kirlllll.ru/volontery/backend/internal/config"
|
||||
"git.kirlllll.ru/volontery/backend/internal/pkg/jwt"
|
||||
"git.kirlllll.ru/volontery/backend/internal/repository"
|
||||
"git.kirlllll.ru/volontery/backend/internal/service"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := run(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func run() error {
|
||||
// Загрузка конфигурации
|
||||
cfg, err := config.Load()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load config: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("Starting server in %s mode", cfg.AppEnv)
|
||||
|
||||
// Подключение к базе данных
|
||||
ctx := context.Background()
|
||||
pool, err := config.NewDBPool(ctx, cfg.DatabaseURL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to connect to database: %w", err)
|
||||
}
|
||||
defer pool.Close()
|
||||
|
||||
log.Println("Connected to database")
|
||||
|
||||
// Инициализация репозиториев
|
||||
repos := repository.New(pool)
|
||||
|
||||
// Инициализация JWT менеджера
|
||||
jwtManager := jwt.NewManager(
|
||||
cfg.JWTSecret,
|
||||
cfg.JWTAccessTokenTTL,
|
||||
cfg.JWTRefreshTokenTTL,
|
||||
)
|
||||
|
||||
// Инициализация сервисов
|
||||
authService := service.NewAuthService(
|
||||
repos.User,
|
||||
repos.Auth,
|
||||
repos.RBAC,
|
||||
jwtManager,
|
||||
)
|
||||
|
||||
userService := service.NewUserService(
|
||||
repos.User,
|
||||
repos.RBAC,
|
||||
)
|
||||
|
||||
requestService := service.NewRequestService(
|
||||
repos.Request,
|
||||
)
|
||||
|
||||
// Создание HTTP сервера
|
||||
server := api.NewServer(
|
||||
cfg,
|
||||
authService,
|
||||
userService,
|
||||
requestService,
|
||||
jwtManager,
|
||||
)
|
||||
|
||||
// Настройка HTTP сервера
|
||||
addr := fmt.Sprintf("%s:%s", cfg.ServerHost, cfg.ServerPort)
|
||||
httpServer := &http.Server{
|
||||
Addr: addr,
|
||||
Handler: server,
|
||||
ReadTimeout: 15 * time.Second,
|
||||
WriteTimeout: 15 * time.Second,
|
||||
IdleTimeout: 60 * time.Second,
|
||||
}
|
||||
|
||||
// Канал для обработки ошибок сервера
|
||||
serverErrors := make(chan error, 1)
|
||||
|
||||
// Запуск HTTP сервера в горутине
|
||||
go func() {
|
||||
log.Printf("Server listening on %s", addr)
|
||||
serverErrors <- httpServer.ListenAndServe()
|
||||
}()
|
||||
|
||||
// Канал для обработки сигналов завершения
|
||||
shutdown := make(chan os.Signal, 1)
|
||||
signal.Notify(shutdown, os.Interrupt, syscall.SIGTERM)
|
||||
|
||||
// Блокируемся до получения сигнала завершения или ошибки сервера
|
||||
select {
|
||||
case err := <-serverErrors:
|
||||
return fmt.Errorf("server error: %w", err)
|
||||
|
||||
case sig := <-shutdown:
|
||||
log.Printf("Received signal %v, starting graceful shutdown", sig)
|
||||
|
||||
// Даем 30 секунд на завершение активных запросов
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := httpServer.Shutdown(ctx); err != nil {
|
||||
httpServer.Close()
|
||||
return fmt.Errorf("failed to gracefully shutdown server: %w", err)
|
||||
}
|
||||
|
||||
log.Println("Server stopped gracefully")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user