add state history
This commit is contained in:
@@ -25,11 +25,13 @@ func Init(di *dig.Container, app *fiber.App) {
|
||||
},
|
||||
})
|
||||
|
||||
serverIdGroup := groups.Group("/server/:id")
|
||||
routeGroups := &common.RouteGroups{
|
||||
Api: groups.Group("/api"),
|
||||
Server: groups.Group("/server"),
|
||||
Config: groups.Group("/server/:id").Group("/config"),
|
||||
Config: serverIdGroup.Group("/config"),
|
||||
Lookup: groups.Group("/lookup"),
|
||||
StateHistory: serverIdGroup.Group("/state-history"),
|
||||
}
|
||||
|
||||
groups.Use(basicAuthConfig)
|
||||
|
||||
@@ -40,6 +40,11 @@ func InitializeControllers(c *dig.Container) {
|
||||
if err != nil {
|
||||
log.Panic("unable to initialize lookup controller")
|
||||
}
|
||||
|
||||
err = c.Invoke(NewStateHistoryController)
|
||||
if err != nil {
|
||||
log.Panic("unable to initialize stateHistory controller")
|
||||
}
|
||||
}
|
||||
|
||||
// FilteredResponse
|
||||
|
||||
43
local/controller/stateHistory.go
Normal file
43
local/controller/stateHistory.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"acc-server-manager/local/service"
|
||||
"acc-server-manager/local/utl/common"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type StateHistoryController struct {
|
||||
service *service.StateHistoryService
|
||||
}
|
||||
|
||||
// NewStateHistoryController
|
||||
// Initializes StateHistoryController.
|
||||
//
|
||||
// Args:
|
||||
// *services.StateHistoryService: StateHistory service
|
||||
// *Fiber.RouterGroup: Fiber Router Group
|
||||
// Returns:
|
||||
// *StateHistoryController: Controller for "StateHistory" interactions
|
||||
func NewStateHistoryController(as *service.StateHistoryService, routeGroups *common.RouteGroups) *StateHistoryController {
|
||||
ac := &StateHistoryController{
|
||||
service: as,
|
||||
}
|
||||
|
||||
routeGroups.StateHistory.Get("/", ac.getAll)
|
||||
|
||||
return ac
|
||||
}
|
||||
|
||||
// getAll returns StateHistorys
|
||||
//
|
||||
// @Summary Return StateHistorys
|
||||
// @Description Return StateHistorys
|
||||
// @Tags StateHistory
|
||||
// @Success 200 {array} string
|
||||
// @Router /v1/StateHistory [get]
|
||||
func (ac *StateHistoryController) getAll(c *fiber.Ctx) error {
|
||||
StateHistoryID, _ := c.ParamsInt("id")
|
||||
StateHistoryModel := ac.service.GetAll(c, StateHistoryID)
|
||||
return c.JSON(StateHistoryModel)
|
||||
}
|
||||
@@ -31,11 +31,6 @@ type PlayerState struct {
|
||||
IsConnected bool
|
||||
}
|
||||
|
||||
type AccServerInstance struct {
|
||||
Model *Server
|
||||
State *ServerState
|
||||
}
|
||||
|
||||
type State struct {
|
||||
Session string `json:"session"`
|
||||
SessionStart time.Time `json:"sessionStart"`
|
||||
@@ -53,4 +48,12 @@ type ServerState struct {
|
||||
MaxConnections int `json:"maxConnections"`
|
||||
// Players map[int]*PlayerState
|
||||
// etc.
|
||||
}
|
||||
|
||||
type StateHistory struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
ServerID uint `json:"serverId" gorm:"not null"`
|
||||
Session string `json:"session"`
|
||||
PlayerCount int `json:"playerCount"`
|
||||
DateCreated time.Time `json:"dateCreated"`
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
// *dig.Container: Dig Container
|
||||
func InitializeRepositories(c *dig.Container) {
|
||||
c.Provide(NewApiRepository)
|
||||
c.Provide(NewStateHistoryRepository)
|
||||
c.Provide(NewServerRepository)
|
||||
c.Provide(NewConfigRepository)
|
||||
c.Provide(NewLookupRepository)
|
||||
|
||||
45
local/repository/stateHistory.go
Normal file
45
local/repository/stateHistory.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"acc-server-manager/local/model"
|
||||
"context"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type StateHistoryRepository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewStateHistoryRepository(db *gorm.DB) *StateHistoryRepository {
|
||||
return &StateHistoryRepository{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
// GetAll
|
||||
// Gets All rows from Server table.
|
||||
//
|
||||
// Args:
|
||||
// context.Context: Application context
|
||||
// Returns:
|
||||
// model.ServerModel: Server object from database.
|
||||
func (as StateHistoryRepository) GetAll(ctx context.Context, id int) *[]model.StateHistory {
|
||||
db := as.db.WithContext(ctx)
|
||||
ServerModel := new([]model.StateHistory)
|
||||
db.Find(&ServerModel).Where("ID = ?", id)
|
||||
return ServerModel
|
||||
}
|
||||
|
||||
// UpdateServer
|
||||
// Updates Server row from Server table.
|
||||
//
|
||||
// Args:
|
||||
// context.Context: Application context
|
||||
// Returns:
|
||||
// model.Server: Server object from database.
|
||||
func (as StateHistoryRepository) Insert(ctx context.Context, body *model.StateHistory) *model.StateHistory {
|
||||
db := as.db.WithContext(ctx)
|
||||
db.Save(body)
|
||||
return body
|
||||
}
|
||||
@@ -8,22 +8,25 @@ import (
|
||||
"log"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type ServerService struct {
|
||||
repository *repository.ServerRepository
|
||||
stateHistoryRepo *repository.StateHistoryRepository
|
||||
apiService *ApiService
|
||||
instances sync.Map
|
||||
configService *ConfigService
|
||||
}
|
||||
|
||||
func NewServerService(repository *repository.ServerRepository, apiService *ApiService, configService *ConfigService) *ServerService {
|
||||
func NewServerService(repository *repository.ServerRepository, stateHistoryRepo *repository.StateHistoryRepository, apiService *ApiService, configService *ConfigService) *ServerService {
|
||||
service := &ServerService{
|
||||
repository: repository,
|
||||
apiService: apiService,
|
||||
configService: configService,
|
||||
stateHistoryRepo: stateHistoryRepo,
|
||||
}
|
||||
servers := repository.GetAll(context.Background())
|
||||
for _, server := range *servers {
|
||||
@@ -40,10 +43,13 @@ func NewServerService(repository *repository.ServerRepository, apiService *ApiSe
|
||||
|
||||
func (s *ServerService) StartAccServerRuntime(server *model.Server) {
|
||||
s.instances.Delete(server.ID)
|
||||
instance := tracking.NewAccServerInstance(server, func(states ...tracking.StateChange) {
|
||||
for _, state := range states {
|
||||
log.Println(tracking.StateChanges[state])
|
||||
}
|
||||
instance := tracking.NewAccServerInstance(server, func(state *model.ServerState, states ...tracking.StateChange) {
|
||||
s.stateHistoryRepo.Insert(context.Background(), &model.StateHistory{
|
||||
ServerID: server.ID,
|
||||
Session: state.Session,
|
||||
PlayerCount: state.PlayerCount,
|
||||
DateCreated: time.Now().UTC(),
|
||||
})
|
||||
})
|
||||
config, _ := DecodeFileName(ConfigurationJson)(server.ConfigPath)
|
||||
cfg := config.(model.Configuration)
|
||||
|
||||
@@ -16,6 +16,7 @@ func InitializeServices(c *dig.Container) {
|
||||
repository.InitializeRepositories(c)
|
||||
|
||||
c.Provide(NewServerService)
|
||||
c.Provide(NewStateHistoryService)
|
||||
c.Provide(NewApiService)
|
||||
c.Provide(NewConfigService)
|
||||
c.Provide(NewLookupService)
|
||||
|
||||
29
local/service/stateHistory.go
Normal file
29
local/service/stateHistory.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"acc-server-manager/local/model"
|
||||
"acc-server-manager/local/repository"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type StateHistoryService struct {
|
||||
repository *repository.StateHistoryRepository
|
||||
}
|
||||
|
||||
func NewStateHistoryService(repository *repository.StateHistoryRepository) *StateHistoryService {
|
||||
return &StateHistoryService{
|
||||
repository: repository,
|
||||
}
|
||||
}
|
||||
|
||||
// GetAll
|
||||
// Gets All rows from StateHistory table.
|
||||
//
|
||||
// Args:
|
||||
// context.Context: Application context
|
||||
// Returns:
|
||||
// string: Application version
|
||||
func (as StateHistoryService) GetAll(ctx *fiber.Ctx, id int) *[]model.StateHistory {
|
||||
return as.repository.GetAll(ctx.UserContext(), id)
|
||||
}
|
||||
@@ -19,6 +19,7 @@ type RouteGroups struct {
|
||||
Server fiber.Router
|
||||
Config fiber.Router
|
||||
Lookup fiber.Router
|
||||
StateHistory fiber.Router
|
||||
}
|
||||
|
||||
func CheckError(err error) {
|
||||
|
||||
@@ -55,6 +55,10 @@ func Migrate(db *gorm.DB) {
|
||||
if err != nil {
|
||||
panic("failed to migrate model.SessionType")
|
||||
}
|
||||
err = db.AutoMigrate(&model.StateHistory{})
|
||||
if err != nil {
|
||||
panic("failed to migrate model.StateHistory")
|
||||
}
|
||||
db.FirstOrCreate(&model.ApiModel{Api: "Works"})
|
||||
|
||||
Seed(db)
|
||||
|
||||
@@ -24,10 +24,10 @@ var StateChanges = map[StateChange]string {
|
||||
type AccServerInstance struct {
|
||||
Model *model.Server
|
||||
State *model.ServerState
|
||||
OnStateChange func(...StateChange)
|
||||
OnStateChange func(*model.ServerState, ...StateChange)
|
||||
}
|
||||
|
||||
func NewAccServerInstance(server *model.Server, onStateChange func(...StateChange)) *AccServerInstance {
|
||||
func NewAccServerInstance(server *model.Server, onStateChange func(*model.ServerState, ...StateChange)) *AccServerInstance {
|
||||
return &AccServerInstance{
|
||||
Model: server,
|
||||
State: &model.ServerState{PlayerCount: 0},
|
||||
@@ -109,8 +109,8 @@ var logStateContain = map[LogStateType]string {
|
||||
|
||||
var sessionChangeRegex = NewRegexHandler(`Session changed: (\w+) -> (\w+)`, logStateContain[SessionChange])
|
||||
var leaderboardUpdateRegex = NewRegexHandler(`Updated leaderboard for (\d+) clients`, logStateContain[LeaderboardUpdate])
|
||||
var udpCountRegex = NewRegexHandler(`Udp message count ((\d+) client`, logStateContain[UDPCount])
|
||||
var clientsOnlineRegex = NewRegexHandler(`(\d+) client(s) online`, logStateContain[ClientsOnline])
|
||||
var udpCountRegex = NewRegexHandler(`Udp message count (\d+) client`, logStateContain[UDPCount])
|
||||
var clientsOnlineRegex = NewRegexHandler(`(\d+) client\(s\) online`, logStateContain[ClientsOnline])
|
||||
|
||||
var logStateRegex = map[LogStateType]*StateRegexHandler {
|
||||
SessionChange: sessionChangeRegex,
|
||||
@@ -136,39 +136,45 @@ func (instance *AccServerInstance) HandleLogLine(line string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (instance *AccServerInstance) UpdateState(callback func(state *model.ServerState)) {
|
||||
func (instance *AccServerInstance) UpdateState(callback func(state *model.ServerState, changes *[]StateChange)) {
|
||||
state := instance.State
|
||||
changes := []StateChange{}
|
||||
state.Lock()
|
||||
defer state.Unlock()
|
||||
callback(state)
|
||||
callback(state, &changes)
|
||||
if (len(changes) > 0) {
|
||||
instance.OnStateChange(state, changes...)
|
||||
}
|
||||
}
|
||||
|
||||
func (instance *AccServerInstance) UpdatePlayerCount(count int) {
|
||||
changes := []StateChange{}
|
||||
instance.UpdateState(func (state *model.ServerState) {
|
||||
instance.UpdateState(func (state *model.ServerState, changes *[]StateChange) {
|
||||
if (count == state.PlayerCount) {
|
||||
return
|
||||
}
|
||||
if (count > 0 && state.PlayerCount == 0) {
|
||||
state.SessionStart = time.Now()
|
||||
changes = append(changes, Session)
|
||||
*changes = append(*changes, Session)
|
||||
} else if (count == 0) {
|
||||
state.SessionStart = time.Time{}
|
||||
changes = append(changes, Session)
|
||||
*changes = append(*changes, Session)
|
||||
}
|
||||
state.PlayerCount = count
|
||||
changes = append(changes, PlayerCount)
|
||||
*changes = append(*changes, PlayerCount)
|
||||
})
|
||||
instance.OnStateChange(changes...)
|
||||
}
|
||||
|
||||
func (instance *AccServerInstance) UpdateSessionChange(session string) {
|
||||
changes := []StateChange{}
|
||||
instance.UpdateState(func (state *model.ServerState) {
|
||||
instance.UpdateState(func (state *model.ServerState, changes *[]StateChange) {
|
||||
if (session == state.Session) {
|
||||
return
|
||||
}
|
||||
if (state.PlayerCount > 0) {
|
||||
state.SessionStart = time.Now()
|
||||
} else {
|
||||
state.SessionStart = time.Time{}
|
||||
}
|
||||
state.Session = session
|
||||
changes = append(changes, Session)
|
||||
*changes = append(*changes, Session)
|
||||
})
|
||||
instance.OnStateChange(changes...)
|
||||
}
|
||||
Reference in New Issue
Block a user