From f077ffd7a71bdb9fb7617f7b680218ab15132dc4 Mon Sep 17 00:00:00 2001 From: Maxim Slipenko Date: Sun, 15 Dec 2024 09:16:51 +0300 Subject: [PATCH] refactor: add cronservice --- cmd/aides-repo-api/main.go | 10 +-- internal/app/app.go | 83 ++++++++++++++++--- internal/config/config.go | 4 + .../controllers/taskcontroller/controller.go | 5 +- internal/router/router.go | 49 +++-------- internal/services/cronservice/service.go | 55 ++++++++++++ internal/services/reposervice/service.go | 37 +++++---- internal/services/taskservice/create.go | 6 +- internal/services/taskservice/service.go | 30 ++++--- internal/services/taskservice/upload.go | 6 +- 10 files changed, 192 insertions(+), 93 deletions(-) create mode 100644 internal/services/cronservice/service.go diff --git a/cmd/aides-repo-api/main.go b/cmd/aides-repo-api/main.go index bd476bb..d3bd61c 100644 --- a/cmd/aides-repo-api/main.go +++ b/cmd/aides-repo-api/main.go @@ -1,11 +1,7 @@ package main import ( - "log" - "net/http" - "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/app" - "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/router" ) func main() { @@ -14,9 +10,7 @@ func main() { panic(err) } - // Конфигурация сервера - router := router.New(app).Setup() + app.Init() - log.Printf("Сервер запущен на порту: %s", app.Config.Port) - http.ListenAndServe(":"+app.Config.Port, router) + app.Run() } diff --git a/internal/app/app.go b/internal/app/app.go index 0b8d304..5b21c59 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -2,35 +2,98 @@ package app import ( "fmt" + "log" + "net/http" "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/config" + "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/controllers/taskcontroller" "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/models" + "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/router" + "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/services/cronservice" + "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/services/reposervice" + "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/services/taskservice" "gorm.io/driver/postgres" "gorm.io/gorm" ) type App struct { - Db *gorm.DB - Config *config.Config + db *gorm.DB + config *config.Config + + repo *reposervice.Service + taskService *taskservice.Service + cron *cronservice.Service + + taskController *taskcontroller.TaskController + router *router.Router +} + +func createDBConnection(cfg *config.Config) (*gorm.DB, error) { + dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", cfg.DBHost, cfg.DBPort, cfg.DBUser, cfg.DBPassword, cfg.DBName) + return gorm.Open(postgres.Open(dsn), &gorm.Config{}) } func New() (*App, error) { cfg := config.New() - dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", - cfg.DBHost, cfg.DBPort, cfg.DBUser, cfg.DBPassword, cfg.DBName) - db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) + db, err := createDBConnection(cfg) if err != nil { return nil, err } db.AutoMigrate(&models.Task{}, &models.GitRepoAltRepoTask{}, &models.RPMFile{}) - db.FirstOrCreate(&models.ALTRepo{ Name: "Sisyphus", }) - return &App{ - Config: cfg, - Db: db, - }, nil + app := App{ + config: cfg, + db: db, + } + + app.createServices() + app.createControllers() + app.createRouter() + + return &app, nil +} + +func (app *App) createServices() { + app.repo = reposervice.New( + app.db, + app.config, + ) + app.taskService = taskservice.New( + app.db, + app.config, + ) + app.cron = cronservice.New( + app.repo, + ) +} + +func (app *App) createControllers() { + app.taskController = taskcontroller.New( + app.taskService, + ) +} + +func (app *App) createRouter() { + app.router = router.New( + app.config, + app.taskController, + ) +} + +func (app *App) initServices() { + app.cron.SetupCronJobs() + app.cron.Start() +} + +func (app *App) Init() { + app.initServices() +} + +func (app *App) Run() { + log.Printf("Сервер запущен на порту: %s", app.config.Port) + http.ListenAndServe(":"+app.config.Port, app.router.Setup()) } diff --git a/internal/config/config.go b/internal/config/config.go index 08ee12d..1d30590 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -28,3 +28,7 @@ func New() *Config { return config } + +func (c *Config) GetUploadDir() string { + return c.UploadDir +} diff --git a/internal/controllers/taskcontroller/controller.go b/internal/controllers/taskcontroller/controller.go index 46efa1b..4428976 100644 --- a/internal/controllers/taskcontroller/controller.go +++ b/internal/controllers/taskcontroller/controller.go @@ -1,18 +1,15 @@ package taskcontroller import ( - "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/app" "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/services/taskservice" ) type TaskController struct { - app *app.App taskService *taskservice.Service } -func New(app *app.App, taskService *taskservice.Service) *TaskController { +func New(taskService *taskservice.Service) *TaskController { return &TaskController{ - app: app, taskService: taskService, } } diff --git a/internal/router/router.go b/internal/router/router.go index 4774e84..555e5fc 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -3,25 +3,27 @@ package router import ( "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" - "github.com/go-co-op/gocron/v2" httpSwagger "github.com/swaggo/http-swagger" - "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/app" + "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/config" "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/controllers/taskcontroller" "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/middlewares" - "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/services/reposervice" - "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/services/taskservice" _ "code.alt-gnome.ru/aides-infra/aides-repo-api/docs" ) type Router struct { - app *app.App + config *config.Config + taskController *taskcontroller.TaskController } -func New(app *app.App) *Router { +func New( + config *config.Config, + taskController *taskcontroller.TaskController, +) *Router { return &Router{ - app: app, + config: config, + taskController: taskController, } } @@ -29,41 +31,14 @@ func (r *Router) Setup() *chi.Mux { router := chi.NewRouter() router.Use(middleware.Logger) - taskService := taskservice.New( - r.app, - ) - - repoService := reposervice.New(r.app) - repoService.ForceUpdate() - - s, _ := gocron.NewScheduler() - defer func() { _ = s.Shutdown() }() - - _, _ = s.NewJob( - gocron.CronJob( - "0 4 * * *", - false, - ), - gocron.NewTask( - func() { - repoService.ForceUpdate() - }, - ), - ) - - taskController := taskcontroller.New( - r.app, - taskService, - ) - - authGuard := middlewares.CreateAuthGuard(r.app.Config) + authGuard := middlewares.CreateAuthGuard(r.config) router.Get("/swagger/*", httpSwagger.WrapHandler) router.Route("/tasks", func(taskRouter chi.Router) { - taskRouter.With(authGuard).Post("/", taskController.Create) + taskRouter.With(authGuard).Post("/", r.taskController.Create) taskRouter.Route("/{taskID}", func(sTaskRouter chi.Router) { - sTaskRouter.With(authGuard).Post("/upload", taskController.Upload) + sTaskRouter.With(authGuard).Post("/upload", r.taskController.Upload) }) }) diff --git a/internal/services/cronservice/service.go b/internal/services/cronservice/service.go new file mode 100644 index 0000000..9ed3787 --- /dev/null +++ b/internal/services/cronservice/service.go @@ -0,0 +1,55 @@ +package cronservice + +import ( + "fmt" + "log" + "time" + + "github.com/go-co-op/gocron/v2" +) + +type RepoService interface { + ForceUpdate() +} + +type Service struct { + repoService RepoService + + scheduler gocron.Scheduler +} + +func New(repo RepoService) *Service { + scheduler, err := gocron.NewScheduler(gocron.WithLocation(time.UTC)) + if err != nil { + log.Fatalf("Не удалось создать планировщик: %v", err) + } + + return &Service{ + scheduler: scheduler, + repoService: repo, + } +} + +func (s *Service) SetupCronJobs() { + _, err := s.scheduler.NewJob( + gocron.CronJob("* * * * *", false), + gocron.NewTask(func() { + fmt.Println("Cron run!") + s.repoService.ForceUpdate() + }), + ) + if err != nil { + log.Printf("Не удалось создать задание cron: %v", err) + } +} + +func (s *Service) Start() { + s.scheduler.Start() +} + +func (s *Service) Shutdown() { + err := s.scheduler.Shutdown() + if err != nil { + log.Printf("Не удалось корректно завершить работу планировщика: %v", err) + } +} diff --git a/internal/services/reposervice/service.go b/internal/services/reposervice/service.go index fa48962..b498392 100644 --- a/internal/services/reposervice/service.go +++ b/internal/services/reposervice/service.go @@ -7,18 +7,23 @@ import ( "path" "strconv" - "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/app" "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/models" "gorm.io/gorm" ) -type Service struct { - app *app.App +type Config interface { + GetUploadDir() string } -func New(app *app.App) *Service { +type Service struct { + db *gorm.DB + config Config +} + +func New(db *gorm.DB, cfg Config) *Service { return &Service{ - app: app, + db: db, + config: cfg, } } @@ -72,11 +77,11 @@ func (s *Service) ForceUpdate() { Name: "Sisyphus", } - s.app.Db. + s.db. Where(&altRepo). First(&altRepo) - s.app.Db.Debug(). + s.db.Debug(). Model(&models.GitRepoAltRepoTask{}). Select("tasks.*"). Joins("JOIN tasks ON tasks.id = git_repo_alt_repo_tasks.last_task_id"). @@ -86,7 +91,7 @@ func (s *Service) ForceUpdate() { Preload("Files"). Find(&tasks) - repoPath := path.Join(s.app.Config.UploadDir, "future_repo", "Sisyphus") + repoPath := path.Join(s.config.GetUploadDir(), "future_repo", "Sisyphus") os.MkdirAll( repoPath, @@ -102,14 +107,14 @@ func (s *Service) ForceUpdate() { for _, el := range tasks { taskPath := path.Join( - s.app.Config.UploadDir, "tasks", strconv.FormatUint(uint64(el.ID), 10), + s.config.GetUploadDir(), "tasks", strconv.FormatUint(uint64(el.ID), 10), ) for _, fileInfo := range el.Files { localFilePath := path.Join( strconv.FormatUint(uint64(el.ID), 10), fileInfo.Name, ) - symLink := path.Join(s.app.Config.UploadDir, "future_repo", "Sisyphus", fileInfo.Arch, "RPMS.aides", fileInfo.Name) + symLink := path.Join(s.config.GetUploadDir(), "future_repo", "Sisyphus", fileInfo.Arch, "RPMS.aides", fileInfo.Name) targetPath := path.Join("../../../../tasks/", localFilePath) createSymlink(targetPath, symLink) @@ -121,7 +126,7 @@ func (s *Service) ForceUpdate() { runGenbasedir(repoPath, arch, repoName) } - s.app.Db.Debug(). + s.db.Debug(). Model(&models.GitRepoAltRepoTask{}). Where(&models.GitRepoAltRepoTask{ ALTRepoID: altRepo.ID, @@ -130,11 +135,11 @@ func (s *Service) ForceUpdate() { "current_task_id", gorm.Expr("last_task_id"), ) - os.MkdirAll(path.Join(s.app.Config.UploadDir, "repo"), os.ModePerm) + os.MkdirAll(path.Join(s.config.GetUploadDir(), "repo"), os.ModePerm) - aPath := path.Join(s.app.Config.UploadDir, "future_repo", "Sisyphus") - bPath := path.Join(s.app.Config.UploadDir, "repo", "Sisyphus") - cPath := path.Join(s.app.Config.UploadDir, "repo", ".Sisyphus") + aPath := path.Join(s.config.GetUploadDir(), "future_repo", "Sisyphus") + bPath := path.Join(s.config.GetUploadDir(), "repo", "Sisyphus") + cPath := path.Join(s.config.GetUploadDir(), "repo", ".Sisyphus") if _, err := os.Stat(bPath); err == nil { fmt.Printf("Moving %s to %s\n", bPath, cPath) @@ -152,5 +157,5 @@ func (s *Service) ForceUpdate() { } - os.RemoveAll(path.Join(s.app.Config.UploadDir, "future_repo")) + os.RemoveAll(path.Join(s.config.GetUploadDir(), "future_repo")) } diff --git a/internal/services/taskservice/create.go b/internal/services/taskservice/create.go index aa81c21..e0b9e70 100644 --- a/internal/services/taskservice/create.go +++ b/internal/services/taskservice/create.go @@ -8,14 +8,14 @@ func (s *Service) Create(repo string) (*models.Task, error) { taskRepo := models.GitRepo{ Name: repo, } - s.app.Db.Debug(). + s.db.Debug(). Where(&taskRepo). FirstOrCreate(&taskRepo) altRepo := models.ALTRepo{ Name: "Sisyphus", } - s.app.Db. + s.db. Where(&altRepo). FirstOrCreate(&altRepo) @@ -25,7 +25,7 @@ func (s *Service) Create(repo string) (*models.Task, error) { Type: models.TypeUpsert, } - result := s.app.Db.Create(&task) + result := s.db.Create(&task) return &task, result.Error } diff --git a/internal/services/taskservice/service.go b/internal/services/taskservice/service.go index 7191eef..9f4a916 100644 --- a/internal/services/taskservice/service.go +++ b/internal/services/taskservice/service.go @@ -5,22 +5,28 @@ import ( "path" "strconv" - "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/app" "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/models" + "gorm.io/gorm" ) -type Service struct { - app *app.App +type Config interface { + GetUploadDir() string } -func New(app *app.App) *Service { +type Service struct { + db *gorm.DB + config Config +} + +func New(db *gorm.DB, config Config) *Service { return &Service{ - app: app, + db: db, + config: config, } } func (s *Service) onTaskComplete(task *models.Task) error { - if err := s.app.Db.Save(&task).Error; err != nil { + if err := s.db.Save(&task).Error; err != nil { return err } @@ -28,13 +34,13 @@ func (s *Service) onTaskComplete(task *models.Task) error { ALTRepoID: 1, RepoID: task.RepoID, } - s.app.Db.Debug(). + s.db.Debug(). Where(&grart). FirstOrCreate(&grart) grart.LastTaskID = &task.ID - if err := s.app.Db.Save(&grart).Error; err != nil { + if err := s.db.Save(&grart).Error; err != nil { return err } @@ -53,7 +59,7 @@ func (s *Service) tasksCleanup(r *models.GitRepoAltRepoTask, N int) { } var lastNTaskIDs []uint - s.app.Db. + s.db. Debug(). Table("tasks"). Select("id"). @@ -67,7 +73,7 @@ func (s *Service) tasksCleanup(r *models.GitRepoAltRepoTask, N int) { excludedTaskIDs = append(excludedTaskIDs, lastNTaskIDs...) var taskIDsToDelete []int - s.app.Db. + s.db. Debug(). Model(&models.Task{}). Select("id"). @@ -77,7 +83,7 @@ func (s *Service) tasksCleanup(r *models.GitRepoAltRepoTask, N int) { Pluck("id", &taskIDsToDelete) if len(taskIDsToDelete) > 0 { - s.app.Db. + s.db. Debug(). Model(&models.Task{}). Where("id IN ?", taskIDsToDelete). @@ -91,7 +97,7 @@ func (s *Service) tasksCleanup(r *models.GitRepoAltRepoTask, N int) { func (s *Service) removeTaskFiles(taskId int) { taskFolderPath := path.Join( - s.app.Config.UploadDir, + s.config.GetUploadDir(), "tasks", strconv.Itoa(taskId), ) diff --git a/internal/services/taskservice/upload.go b/internal/services/taskservice/upload.go index 4334721..3263bff 100644 --- a/internal/services/taskservice/upload.go +++ b/internal/services/taskservice/upload.go @@ -41,7 +41,7 @@ func (s *Service) Upload(input *TaskUploadInput) error { files := input.Files task := models.Task{} - result := s.app.Db.Preload("Repo").Where( + result := s.db.Preload("Repo").Where( "id = ?", taskID, ).First(&task) /*.Where( @@ -56,7 +56,7 @@ func (s *Service) Upload(input *TaskUploadInput) error { } localPath := path.Join(input.TaskID) - taskFolderPath := path.Join(s.app.Config.UploadDir, "tasks", localPath) + taskFolderPath := path.Join(s.config.GetUploadDir(), "tasks", localPath) os.MkdirAll(taskFolderPath, os.ModePerm) for _, fileHeader := range files { @@ -103,7 +103,7 @@ func (s *Service) Upload(input *TaskUploadInput) error { Task: task, } - if err := s.app.Db.Save(&f).Error; err != nil { + if err := s.db.Save(&f).Error; err != nil { return err }