195 lines
6.2 KiB
Go
195 lines
6.2 KiB
Go
|
|
package svc
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"fmt"
|
||
|
|
"os"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"haixun-backend/internal/config"
|
||
|
|
libmongo "haixun-backend/internal/library/mongo"
|
||
|
|
libredis "haixun-backend/internal/library/redis"
|
||
|
|
"haixun-backend/internal/library/validate"
|
||
|
|
"haixun-backend/internal/middleware"
|
||
|
|
aisettings "haixun-backend/internal/model/ai/usecase"
|
||
|
|
authrepodomain "haixun-backend/internal/model/auth/domain/repository"
|
||
|
|
authdomain "haixun-backend/internal/model/auth/domain/usecase"
|
||
|
|
authrepo "haixun-backend/internal/model/auth/repository"
|
||
|
|
authuc "haixun-backend/internal/model/auth/usecase"
|
||
|
|
jobrepo "haixun-backend/internal/model/job/repository"
|
||
|
|
jobusecase "haixun-backend/internal/model/job/usecase"
|
||
|
|
memberdomain "haixun-backend/internal/model/member/domain/usecase"
|
||
|
|
memberrepo "haixun-backend/internal/model/member/repository"
|
||
|
|
memberuc "haixun-backend/internal/model/member/usecase"
|
||
|
|
permissiondomain "haixun-backend/internal/model/permission/domain/usecase"
|
||
|
|
permissionrepo "haixun-backend/internal/model/permission/repository"
|
||
|
|
permissionuc "haixun-backend/internal/model/permission/usecase"
|
||
|
|
settingrepo "haixun-backend/internal/model/setting/repository"
|
||
|
|
settingusecase "haixun-backend/internal/model/setting/usecase"
|
||
|
|
jobworker "haixun-backend/internal/worker/job"
|
||
|
|
|
||
|
|
goredis "github.com/redis/go-redis/v9"
|
||
|
|
"github.com/zeromicro/go-zero/rest"
|
||
|
|
)
|
||
|
|
|
||
|
|
type ServiceContext struct {
|
||
|
|
Config config.Config
|
||
|
|
Validator *validate.Validate
|
||
|
|
Mongo *libmongo.Client
|
||
|
|
Redis *goredis.Client
|
||
|
|
|
||
|
|
Setting settingusecase.UseCase
|
||
|
|
AI aisettings.UseCase
|
||
|
|
Job jobusecase.UseCase
|
||
|
|
AuthToken authdomain.TokenUseCase
|
||
|
|
Member memberdomain.UseCase
|
||
|
|
Permission permissiondomain.UseCase
|
||
|
|
|
||
|
|
// Middlewares mounted per route group via generate/api `middleware:` directive.
|
||
|
|
AuthJWT rest.Middleware
|
||
|
|
MemberAuth rest.Middleware
|
||
|
|
|
||
|
|
stopWorker context.CancelFunc
|
||
|
|
stopScheduler context.CancelFunc
|
||
|
|
stopReaper context.CancelFunc
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||
|
|
ctx := context.Background()
|
||
|
|
mongoClient, err := libmongo.NewClient(ctx, c.Mongo)
|
||
|
|
if err != nil {
|
||
|
|
panic(err)
|
||
|
|
}
|
||
|
|
redisClient := libredis.NewClient(c.Redis)
|
||
|
|
|
||
|
|
settingRepository := settingrepo.NewMongoRepository(mongoClient.Database())
|
||
|
|
if err := settingRepository.EnsureIndexes(ctx); err != nil {
|
||
|
|
panic(err)
|
||
|
|
}
|
||
|
|
settingUseCase := settingusecase.NewUseCase(settingRepository)
|
||
|
|
|
||
|
|
var tokenRevokeStore authrepodomain.TokenRevokeStore
|
||
|
|
if redisClient != nil {
|
||
|
|
tokenRevokeStore = authrepo.NewRedisTokenRevokeStore(redisClient)
|
||
|
|
}
|
||
|
|
authTokenUseCase := authuc.NewTokenUseCase(c.Auth, tokenRevokeStore)
|
||
|
|
|
||
|
|
memberRepository := memberrepo.NewMongoRepository(mongoClient.Database())
|
||
|
|
if err := memberRepository.EnsureIndexes(ctx); err != nil {
|
||
|
|
panic(err)
|
||
|
|
}
|
||
|
|
memberUseCase := memberuc.NewUseCase(memberRepository, authTokenUseCase)
|
||
|
|
|
||
|
|
permissionRepository := permissionrepo.NewMongoPermissionRepository(mongoClient.Database())
|
||
|
|
rolePermissionRepository := permissionrepo.NewMongoRolePermissionRepository(mongoClient.Database())
|
||
|
|
if err := permissionRepository.EnsureIndexes(ctx); err != nil {
|
||
|
|
panic(err)
|
||
|
|
}
|
||
|
|
if err := rolePermissionRepository.EnsureIndexes(ctx); err != nil {
|
||
|
|
panic(err)
|
||
|
|
}
|
||
|
|
permissionUseCase := permissionuc.NewUseCase(permissionRepository, rolePermissionRepository)
|
||
|
|
if err := permissionUseCase.EnsureDefaultPermissions(ctx); err != nil {
|
||
|
|
panic(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
jobTemplateRepository := jobrepo.NewMongoTemplateRepository(mongoClient.Database())
|
||
|
|
jobRunRepository := jobrepo.NewMongoRunRepository(mongoClient.Database())
|
||
|
|
jobScheduleRepository := jobrepo.NewMongoScheduleRepository(mongoClient.Database())
|
||
|
|
jobEventRepository := jobrepo.NewMongoEventRepository(mongoClient.Database())
|
||
|
|
jobQueueRepository := jobrepo.NewRedisQueueRepository(redisClient)
|
||
|
|
if err := jobTemplateRepository.EnsureIndexes(ctx); err != nil {
|
||
|
|
panic(err)
|
||
|
|
}
|
||
|
|
if err := jobRunRepository.EnsureIndexes(ctx); err != nil {
|
||
|
|
panic(err)
|
||
|
|
}
|
||
|
|
if err := jobScheduleRepository.EnsureIndexes(ctx); err != nil {
|
||
|
|
panic(err)
|
||
|
|
}
|
||
|
|
if err := jobEventRepository.EnsureIndexes(ctx); err != nil {
|
||
|
|
panic(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
jobUseCase := jobusecase.NewUseCase(jobTemplateRepository, jobRunRepository, jobScheduleRepository, jobEventRepository, jobQueueRepository)
|
||
|
|
if err := jobUseCase.EnsureDemoTemplate(ctx); err != nil {
|
||
|
|
panic(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
sc := &ServiceContext{
|
||
|
|
Config: c,
|
||
|
|
Validator: validate.New(),
|
||
|
|
Mongo: mongoClient,
|
||
|
|
Redis: redisClient,
|
||
|
|
Setting: settingUseCase,
|
||
|
|
AI: aisettings.NewUseCase(),
|
||
|
|
Job: jobUseCase,
|
||
|
|
AuthToken: authTokenUseCase,
|
||
|
|
Member: memberUseCase,
|
||
|
|
Permission: permissionUseCase,
|
||
|
|
}
|
||
|
|
|
||
|
|
hostname, _ := os.Hostname()
|
||
|
|
if c.JobWorker.Enabled && redisClient != nil {
|
||
|
|
workerType := c.JobWorker.WorkerType
|
||
|
|
if workerType == "" {
|
||
|
|
workerType = "go"
|
||
|
|
}
|
||
|
|
workerID := c.JobWorker.WorkerID
|
||
|
|
if workerID == "" {
|
||
|
|
workerID = fmt.Sprintf("%s-%s-worker", hostname, workerType)
|
||
|
|
}
|
||
|
|
workerCtx, cancel := context.WithCancel(context.Background())
|
||
|
|
sc.stopWorker = cancel
|
||
|
|
runner := jobworker.NewRunner(workerID, workerType, jobUseCase)
|
||
|
|
go runner.Start(workerCtx)
|
||
|
|
}
|
||
|
|
|
||
|
|
if c.JobScheduler.Enabled && redisClient != nil {
|
||
|
|
schedulerHolder := fmt.Sprintf("%s-scheduler", hostname)
|
||
|
|
interval := time.Duration(c.JobScheduler.IntervalSeconds) * time.Second
|
||
|
|
if interval <= 0 {
|
||
|
|
interval = time.Minute
|
||
|
|
}
|
||
|
|
schedulerCtx, cancel := context.WithCancel(context.Background())
|
||
|
|
sc.stopScheduler = cancel
|
||
|
|
scheduler := jobworker.NewScheduler(schedulerHolder, jobUseCase)
|
||
|
|
go scheduler.Start(schedulerCtx, interval)
|
||
|
|
}
|
||
|
|
|
||
|
|
if c.JobReaper.Enabled && redisClient != nil {
|
||
|
|
interval := time.Duration(c.JobReaper.IntervalSeconds) * time.Second
|
||
|
|
if interval <= 0 {
|
||
|
|
interval = 30 * time.Second
|
||
|
|
}
|
||
|
|
reaperCtx, cancel := context.WithCancel(context.Background())
|
||
|
|
sc.stopReaper = cancel
|
||
|
|
reaper := jobworker.NewReaper(jobUseCase)
|
||
|
|
go reaper.Start(reaperCtx, interval)
|
||
|
|
}
|
||
|
|
|
||
|
|
sc.AuthJWT = middleware.NewAuthJWTMiddleware(sc.AuthToken, sc.Config.Auth).Handle
|
||
|
|
sc.MemberAuth = middleware.NewMemberAuthMiddleware(sc.AuthToken, sc.Config.Auth).Handle
|
||
|
|
|
||
|
|
return sc
|
||
|
|
}
|
||
|
|
|
||
|
|
func (sc *ServiceContext) Close(ctx context.Context) {
|
||
|
|
if sc == nil {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if sc.stopWorker != nil {
|
||
|
|
sc.stopWorker()
|
||
|
|
}
|
||
|
|
if sc.stopScheduler != nil {
|
||
|
|
sc.stopScheduler()
|
||
|
|
}
|
||
|
|
if sc.stopReaper != nil {
|
||
|
|
sc.stopReaper()
|
||
|
|
}
|
||
|
|
_ = sc.Mongo.Close(ctx)
|
||
|
|
if sc.Redis != nil {
|
||
|
|
_ = sc.Redis.Close()
|
||
|
|
}
|
||
|
|
}
|