108 lines
3.3 KiB
Go
108 lines
3.3 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/config"
|
|
"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http"
|
|
"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/scheduler"
|
|
"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/leaderelection"
|
|
)
|
|
|
|
// Application represents the main application
|
|
type Application struct {
|
|
cfg *config.Config
|
|
logger *zap.Logger
|
|
server *http.Server
|
|
leaderElection leaderelection.LeaderElection
|
|
quotaScheduler *scheduler.QuotaResetScheduler
|
|
ipCleanupScheduler *scheduler.IPCleanupScheduler
|
|
}
|
|
|
|
// ProvideApplication creates a new Application
|
|
func ProvideApplication(
|
|
cfg *config.Config,
|
|
logger *zap.Logger,
|
|
server *http.Server,
|
|
leaderElection leaderelection.LeaderElection,
|
|
quotaScheduler *scheduler.QuotaResetScheduler,
|
|
ipCleanupScheduler *scheduler.IPCleanupScheduler,
|
|
) *Application {
|
|
return &Application{
|
|
cfg: cfg,
|
|
logger: logger,
|
|
server: server,
|
|
leaderElection: leaderElection,
|
|
quotaScheduler: quotaScheduler,
|
|
ipCleanupScheduler: ipCleanupScheduler,
|
|
}
|
|
}
|
|
|
|
// Run starts the application
|
|
func (a *Application) Run(ctx context.Context) error {
|
|
a.logger.Info("")
|
|
a.logger.Info("╔═══════════════════════════════════════════════╗")
|
|
a.logger.Info("║ MaplePress Backend Starting... ║")
|
|
a.logger.Info("╚═══════════════════════════════════════════════╝")
|
|
a.logger.Info("",
|
|
zap.String("environment", a.cfg.App.Environment),
|
|
zap.String("version", a.cfg.App.Version))
|
|
a.logger.Info("")
|
|
|
|
// Start leader election in background if enabled
|
|
if a.cfg.LeaderElection.Enabled {
|
|
go func() {
|
|
a.logger.Info("starting leader election")
|
|
if err := a.leaderElection.Start(ctx); err != nil {
|
|
a.logger.Error("leader election stopped", zap.Error(err))
|
|
}
|
|
}()
|
|
} else {
|
|
a.logger.Warn("leader election is DISABLED - all schedulers will run on every instance")
|
|
}
|
|
|
|
// Start quota reset scheduler
|
|
if err := a.quotaScheduler.Start(); err != nil {
|
|
a.logger.Error("failed to start quota scheduler", zap.Error(err))
|
|
return err
|
|
}
|
|
|
|
// Start IP cleanup scheduler for GDPR compliance
|
|
if err := a.ipCleanupScheduler.Start(); err != nil {
|
|
a.logger.Error("failed to start IP cleanup scheduler", zap.Error(err))
|
|
return err
|
|
}
|
|
|
|
return a.server.Start()
|
|
}
|
|
|
|
// Shutdown gracefully shuts down the application
|
|
func (a *Application) Shutdown(ctx context.Context) error {
|
|
a.logger.Info("shutting down MaplePress Backend")
|
|
|
|
// Stop leader election first if enabled
|
|
if a.cfg.LeaderElection.Enabled {
|
|
a.logger.Info("stopping leader election")
|
|
if err := a.leaderElection.Stop(); err != nil {
|
|
a.logger.Error("failed to stop leader election", zap.Error(err))
|
|
}
|
|
}
|
|
|
|
// Stop quota scheduler
|
|
a.quotaScheduler.Stop()
|
|
|
|
// Stop IP cleanup scheduler
|
|
a.ipCleanupScheduler.Stop()
|
|
|
|
if err := a.server.Shutdown(ctx); err != nil {
|
|
a.logger.Error("failed to shutdown server", zap.Error(err))
|
|
return err
|
|
}
|
|
|
|
// Sync logger before exit
|
|
a.logger.Sync()
|
|
|
|
return nil
|
|
}
|