This repository has been archived on 2024-04-06. You can view files and clone it, but cannot push or open issues or pull requests.
core-old/internal/service/job.go
Dawid Wysokiński cde9990810
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
refactor: refresh servers cmd - send url instead of just host in payload
2023-02-26 10:20:32 +01:00

259 lines
6.5 KiB
Go

package service
import (
"context"
"fmt"
"time"
"gitea.dwysokinski.me/twhelp/core/internal/domain"
)
type VersionLister interface {
List(ctx context.Context) ([]domain.Version, error)
}
type ServerLister interface {
List(ctx context.Context, params domain.ListServersParams) ([]domain.Server, error)
}
type ServerPublisher interface {
CmdRefresh(ctx context.Context, payloads ...domain.RefreshServersCmdPayload) error
}
type EnnoblementPublisher interface {
CmdRefresh(ctx context.Context, payloads ...domain.RefreshEnnoblementsCmdPayload) error
}
type SnapshotPublisher interface {
CmdCreatePlayers(ctx context.Context, payloads ...domain.CreateSnapshotsCmdPayload) error
CmdCreateTribes(ctx context.Context, payloads ...domain.CreateSnapshotsCmdPayload) error
}
type CleanUper interface {
CleanUp(ctx context.Context, srv domain.Server) error
}
type Job struct {
versionSvc VersionLister
serverSvc ServerLister
serverPublisher ServerPublisher
ennoblementPublisher EnnoblementPublisher
snapshotPublisher SnapshotPublisher
cleaners []CleanUper
}
func NewJob(
versionSvc VersionLister,
serverSvc ServerLister,
serverPublisher ServerPublisher,
ennoblementPublisher EnnoblementPublisher,
snapshotPublisher SnapshotPublisher,
cleaners []CleanUper,
) *Job {
return &Job{
versionSvc: versionSvc,
serverSvc: serverSvc,
serverPublisher: serverPublisher,
ennoblementPublisher: ennoblementPublisher,
snapshotPublisher: snapshotPublisher,
cleaners: cleaners,
}
}
func (j *Job) UpdateData(ctx context.Context) error {
versions, err := j.versionSvc.List(ctx)
if err != nil {
return fmt.Errorf("VersionService.List: %w", err)
}
payloads := make([]domain.RefreshServersCmdPayload, 0, len(versions))
for _, v := range versions {
payloads = append(payloads, domain.RefreshServersCmdPayload{
URL: v.URL(),
VersionCode: v.Code,
})
}
err = j.serverPublisher.CmdRefresh(ctx, payloads...)
if err != nil {
return fmt.Errorf("ServerPublisher.CmdRefresh: %w", err)
}
return nil
}
func (j *Job) UpdateEnnoblements(ctx context.Context) error {
servers, err := j.serverSvc.List(ctx, domain.ListServersParams{
Special: domain.NullBool{
Bool: false,
Valid: true,
},
Open: domain.NullBool{
Bool: true,
Valid: true,
},
Pagination: domain.Pagination{
Limit: serverMaxLimit,
},
})
if err != nil {
return fmt.Errorf("ServerService.List: %w", err)
}
payloads := make([]domain.RefreshEnnoblementsCmdPayload, 0, len(servers))
for _, srv := range servers {
payloads = append(payloads, domain.RefreshEnnoblementsCmdPayload{
Key: srv.Key,
URL: srv.URL,
VersionCode: srv.VersionCode,
})
}
err = j.ennoblementPublisher.CmdRefresh(ctx, payloads...)
if err != nil {
return fmt.Errorf("EnnoblementPublisher.CmdRefresh: %w", err)
}
return nil
}
func (j *Job) CreateSnapshots(ctx context.Context) error {
versions, err := j.versionSvc.List(ctx)
if err != nil {
return fmt.Errorf("VersionService.List: %w", err)
}
for _, v := range versions {
verWithLoc := versionWithLocation{
Version: v,
}
verWithLoc.loc, err = time.LoadLocation(v.Timezone)
if err != nil {
return fmt.Errorf("time.LoadLocation (timezone=%s): %w", v.Timezone, err)
}
if err = j.publishCreatePlayerSnapshotsCmds(ctx, verWithLoc); err != nil {
return fmt.Errorf("couldn't send update snapshots cmds (version=%s): %w", v.Code, err)
}
if err = j.publishCreateTribeSnapshotsCmds(ctx, verWithLoc); err != nil {
return fmt.Errorf("couldn't send update snapshots cmds (version=%s): %w", v.Code, err)
}
}
return nil
}
type versionWithLocation struct {
domain.Version
loc *time.Location
}
func (j *Job) publishCreatePlayerSnapshotsCmds(ctx context.Context, v versionWithLocation) error {
return j.publishCreateSnapshotsCmds(
ctx,
v,
j.snapshotPublisher.CmdCreatePlayers,
func(params domain.ListServersParams, date time.Time) domain.ListServersParams {
params.PlayerSnapshotsCreatedAtLT = date
return params
},
)
}
func (j *Job) publishCreateTribeSnapshotsCmds(ctx context.Context, v versionWithLocation) error {
return j.publishCreateSnapshotsCmds(
ctx,
v,
j.snapshotPublisher.CmdCreateTribes,
func(params domain.ListServersParams, date time.Time) domain.ListServersParams {
params.TribeSnapshotsCreatedAtLT = date
return params
},
)
}
func (j *Job) publishCreateSnapshotsCmds(
ctx context.Context,
v versionWithLocation,
publish func(ctx context.Context, payloads ...domain.CreateSnapshotsCmdPayload) error,
setDate func(params domain.ListServersParams, date time.Time) domain.ListServersParams,
) error {
year, month, day := time.Now().In(v.loc).Date()
servers, err := j.serverSvc.List(ctx, setDate(domain.ListServersParams{
Special: domain.NullBool{
Bool: false,
Valid: true,
},
Open: domain.NullBool{
Bool: true,
Valid: true,
},
Pagination: domain.Pagination{
Limit: serverMaxLimit,
},
VersionCodes: []string{v.Code},
}, time.Date(year, month, day, 0, 0, 0, 0, v.loc)))
if err != nil {
return fmt.Errorf("ServerService.List: %w", err)
}
date := time.Date(year, month, day, 0, 0, 0, 0, time.UTC)
if err = publish(ctx, newCreateSnapshotsCmdPayloads(servers, date)...); err != nil {
return fmt.Errorf("SnapshotPublisher.CmdCreatePlayers: %w", err)
}
return nil
}
func (j *Job) CleanUp(ctx context.Context) error {
versions, err := j.versionSvc.List(ctx)
if err != nil {
return fmt.Errorf("VersionService: %w", err)
}
for _, v := range versions {
servers, err := j.serverSvc.List(ctx, domain.ListServersParams{
Special: domain.NullBool{
Bool: false,
Valid: true,
},
Open: domain.NullBool{
Bool: false,
Valid: true,
},
VersionCodes: []string{v.Code},
Pagination: domain.Pagination{
Limit: serverMaxLimit,
},
})
if err != nil {
return fmt.Errorf("%s: ServerService.List: %w", v.Code, err)
}
for _, srv := range servers {
for _, c := range j.cleaners {
if err := c.CleanUp(ctx, srv); err != nil {
return fmt.Errorf("%s: %w", srv.Key, err)
}
}
}
}
return nil
}
func newCreateSnapshotsCmdPayloads(servers []domain.Server, date time.Time) []domain.CreateSnapshotsCmdPayload {
payloads := make([]domain.CreateSnapshotsCmdPayload, 0, len(servers))
for _, srv := range servers {
payloads = append(payloads, domain.CreateSnapshotsCmdPayload{
Key: srv.Key,
VersionCode: srv.VersionCode,
Date: date,
})
}
return payloads
}