more caching and auth middleware
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"acc-server-manager/local/middleware"
|
||||||
"acc-server-manager/local/service"
|
"acc-server-manager/local/service"
|
||||||
"acc-server-manager/local/utl/common"
|
"acc-server-manager/local/utl/common"
|
||||||
"acc-server-manager/local/utl/error_handler"
|
"acc-server-manager/local/utl/error_handler"
|
||||||
@@ -22,17 +23,19 @@ type ApiController struct {
|
|||||||
// *Fiber.RouterGroup: Fiber Router Group
|
// *Fiber.RouterGroup: Fiber Router Group
|
||||||
// Returns:
|
// Returns:
|
||||||
// *ApiController: Controller for "api" interactions
|
// *ApiController: Controller for "api" interactions
|
||||||
func NewApiController(as *service.ApiService, routeGroups *common.RouteGroups) *ApiController {
|
func NewApiController(as *service.ApiService, routeGroups *common.RouteGroups, auth *middleware.AuthMiddleware) *ApiController {
|
||||||
ac := &ApiController{
|
ac := &ApiController{
|
||||||
service: as,
|
service: as,
|
||||||
errorHandler: error_handler.NewControllerErrorHandler(),
|
errorHandler: error_handler.NewControllerErrorHandler(),
|
||||||
}
|
}
|
||||||
|
|
||||||
routeGroups.Api.Get("/", ac.getFirst)
|
apiGroup := routeGroups.Api
|
||||||
routeGroups.Api.Get("/:service", ac.getStatus)
|
apiGroup.Use(auth.Authenticate)
|
||||||
routeGroups.Api.Post("/start", ac.startServer)
|
apiGroup.Get("/", ac.getFirst)
|
||||||
routeGroups.Api.Post("/stop", ac.stopServer)
|
apiGroup.Get("/:service", ac.getStatus)
|
||||||
routeGroups.Api.Post("/restart", ac.restartServer)
|
apiGroup.Post("/start", ac.startServer)
|
||||||
|
apiGroup.Post("/stop", ac.stopServer)
|
||||||
|
apiGroup.Post("/restart", ac.restartServer)
|
||||||
|
|
||||||
return ac
|
return ac
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"acc-server-manager/local/middleware"
|
||||||
"acc-server-manager/local/service"
|
"acc-server-manager/local/service"
|
||||||
"acc-server-manager/local/utl/common"
|
"acc-server-manager/local/utl/common"
|
||||||
"acc-server-manager/local/utl/error_handler"
|
"acc-server-manager/local/utl/error_handler"
|
||||||
@@ -24,16 +25,18 @@ type ConfigController struct {
|
|||||||
// *Fiber.RouterGroup: Fiber Router Group
|
// *Fiber.RouterGroup: Fiber Router Group
|
||||||
// Returns:
|
// Returns:
|
||||||
// *ConfigController: Controller for "Config" interactions
|
// *ConfigController: Controller for "Config" interactions
|
||||||
func NewConfigController(as *service.ConfigService, routeGroups *common.RouteGroups, as2 *service.ApiService) *ConfigController {
|
func NewConfigController(as *service.ConfigService, routeGroups *common.RouteGroups, as2 *service.ApiService, auth *middleware.AuthMiddleware) *ConfigController {
|
||||||
ac := &ConfigController{
|
ac := &ConfigController{
|
||||||
service: as,
|
service: as,
|
||||||
apiService: as2,
|
apiService: as2,
|
||||||
errorHandler: error_handler.NewControllerErrorHandler(),
|
errorHandler: error_handler.NewControllerErrorHandler(),
|
||||||
}
|
}
|
||||||
|
|
||||||
routeGroups.Config.Put("/:file", ac.UpdateConfig)
|
configGroup := routeGroups.Config
|
||||||
routeGroups.Config.Get("/:file", ac.GetConfig)
|
configGroup.Use(auth.Authenticate)
|
||||||
routeGroups.Config.Get("/", ac.GetConfigs)
|
configGroup.Put("/:file", ac.UpdateConfig)
|
||||||
|
configGroup.Get("/:file", ac.GetConfig)
|
||||||
|
configGroup.Get("/", ac.GetConfigs)
|
||||||
|
|
||||||
return ac
|
return ac
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ type StatusCache struct {
|
|||||||
|
|
||||||
// CacheConfig holds configuration for cache behavior
|
// CacheConfig holds configuration for cache behavior
|
||||||
type CacheConfig struct {
|
type CacheConfig struct {
|
||||||
ExpirationTime time.Duration // How long before a cache entry expires
|
ExpirationTime time.Duration // How long before a cache entry expires
|
||||||
ThrottleTime time.Duration // Minimum time between status checks
|
ThrottleTime time.Duration // Minimum time between status checks
|
||||||
DefaultStatus ServiceStatus // Default status to return when throttled
|
DefaultStatus ServiceStatus // Default status to return when throttled
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerStatusCache manages cached server statuses
|
// ServerStatusCache manages cached server statuses
|
||||||
@@ -73,6 +73,15 @@ func (c *ServerStatusCache) UpdateStatus(serviceName string, status ServiceStatu
|
|||||||
c.lastChecked[serviceName] = time.Now()
|
c.lastChecked[serviceName] = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InvalidateStatus removes a specific service from the cache
|
||||||
|
func (c *ServerStatusCache) InvalidateStatus(serviceName string) {
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
|
delete(c.cache, serviceName)
|
||||||
|
delete(c.lastChecked, serviceName)
|
||||||
|
}
|
||||||
|
|
||||||
// Clear removes all entries from the cache
|
// Clear removes all entries from the cache
|
||||||
func (c *ServerStatusCache) Clear() {
|
func (c *ServerStatusCache) Clear() {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
@@ -100,7 +109,7 @@ func NewLookupCache() *LookupCache {
|
|||||||
func (c *LookupCache) Get(key string) (interface{}, bool) {
|
func (c *LookupCache) Get(key string) (interface{}, bool) {
|
||||||
c.RLock()
|
c.RLock()
|
||||||
defer c.RUnlock()
|
defer c.RUnlock()
|
||||||
|
|
||||||
value, exists := c.data[key]
|
value, exists := c.data[key]
|
||||||
if exists {
|
if exists {
|
||||||
logging.Debug("Cache HIT for key: %s", key)
|
logging.Debug("Cache HIT for key: %s", key)
|
||||||
@@ -114,7 +123,7 @@ func (c *LookupCache) Get(key string) (interface{}, bool) {
|
|||||||
func (c *LookupCache) Set(key string, value interface{}) {
|
func (c *LookupCache) Set(key string, value interface{}) {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
defer c.Unlock()
|
defer c.Unlock()
|
||||||
|
|
||||||
c.data[key] = value
|
c.data[key] = value
|
||||||
logging.Debug("Cache SET for key: %s", key)
|
logging.Debug("Cache SET for key: %s", key)
|
||||||
}
|
}
|
||||||
@@ -123,7 +132,7 @@ func (c *LookupCache) Set(key string, value interface{}) {
|
|||||||
func (c *LookupCache) Clear() {
|
func (c *LookupCache) Clear() {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
defer c.Unlock()
|
defer c.Unlock()
|
||||||
|
|
||||||
c.data = make(map[string]interface{})
|
c.data = make(map[string]interface{})
|
||||||
logging.Debug("Cache CLEARED")
|
logging.Debug("Cache CLEARED")
|
||||||
}
|
}
|
||||||
@@ -285,4 +294,4 @@ func (c *ServerConfigCache) Clear() {
|
|||||||
c.event = make(map[string]*ConfigEntry[EventConfig])
|
c.event = make(map[string]*ConfigEntry[EventConfig])
|
||||||
c.eventRules = make(map[string]*ConfigEntry[EventRules])
|
c.eventRules = make(map[string]*ConfigEntry[EventRules])
|
||||||
c.settings = make(map[string]*ConfigEntry[ServerSettings])
|
c.settings = make(map[string]*ConfigEntry[ServerSettings])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,6 +123,25 @@ func (as *ApiService) StatusServer(serviceName string) (string, error) {
|
|||||||
return as.windowsService.Status(context.Background(), serviceName)
|
return as.windowsService.Status(context.Background(), serviceName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCachedStatus gets the cached status for a service name without requiring fiber context
|
||||||
|
func (as *ApiService) GetCachedStatus(serviceName string) (string, error) {
|
||||||
|
// Try to get status from cache
|
||||||
|
if status, shouldCheck := as.statusCache.GetStatus(serviceName); !shouldCheck {
|
||||||
|
return status.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// If cache miss or expired, check actual status
|
||||||
|
statusStr, err := as.StatusServer(serviceName)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse and update cache with new status
|
||||||
|
status := model.ParseServiceStatus(statusStr)
|
||||||
|
as.statusCache.UpdateStatus(serviceName, status)
|
||||||
|
return status.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (as *ApiService) StartServer(serviceName string) (string, error) {
|
func (as *ApiService) StartServer(serviceName string) (string, error) {
|
||||||
status, err := as.windowsService.Start(context.Background(), serviceName)
|
status, err := as.windowsService.Start(context.Background(), serviceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -210,6 +210,9 @@ func (s *ServerService) handleStateChange(server *model.Server, state *model.Ser
|
|||||||
// Update session duration when session changes
|
// Update session duration when session changes
|
||||||
s.updateSessionDuration(server, state.Session)
|
s.updateSessionDuration(server, state.Session)
|
||||||
|
|
||||||
|
// Invalidate status cache when server state changes
|
||||||
|
s.apiService.statusCache.InvalidateStatus(server.ServiceName)
|
||||||
|
|
||||||
// Cancel existing timer if any
|
// Cancel existing timer if any
|
||||||
if debouncer, exists := s.debouncers.Load(server.ID); exists {
|
if debouncer, exists := s.debouncers.Load(server.ID); exists {
|
||||||
pending := debouncer.(*pendingState)
|
pending := debouncer.(*pendingState)
|
||||||
@@ -278,7 +281,7 @@ func (s *ServerService) GetAll(ctx *fiber.Ctx, filter *model.ServerFilter) (*[]m
|
|||||||
|
|
||||||
for i := range *servers {
|
for i := range *servers {
|
||||||
server := &(*servers)[i]
|
server := &(*servers)[i]
|
||||||
status, err := s.apiService.StatusServer(server.ServiceName)
|
status, err := s.apiService.GetCachedStatus(server.ServiceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logging.Error("Failed to get status for server %s: %v", server.ServiceName, err)
|
logging.Error("Failed to get status for server %s: %v", server.ServiceName, err)
|
||||||
}
|
}
|
||||||
@@ -309,7 +312,7 @@ func (as *ServerService) GetById(ctx *fiber.Ctx, serverID uuid.UUID) (*model.Ser
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
status, err := as.apiService.StatusServer(server.ServiceName)
|
status, err := as.apiService.GetCachedStatus(server.ServiceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logging.Error(err.Error())
|
logging.Error(err.Error())
|
||||||
}
|
}
|
||||||
@@ -427,6 +430,9 @@ func (s *ServerService) DeleteServer(ctx *fiber.Ctx, serverID uuid.UUID) error {
|
|||||||
s.debouncers.Delete(server.ID)
|
s.debouncers.Delete(server.ID)
|
||||||
s.sessionIDs.Delete(server.ID)
|
s.sessionIDs.Delete(server.ID)
|
||||||
|
|
||||||
|
// Invalidate status cache for deleted server
|
||||||
|
s.apiService.statusCache.InvalidateStatus(server.ServiceName)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,6 +473,8 @@ func (s *ServerService) UpdateServer(ctx *fiber.Ctx, server *model.Server) error
|
|||||||
if err := s.configureFirewall(server); err != nil {
|
if err := s.configureFirewall(server); err != nil {
|
||||||
return fmt.Errorf("failed to update firewall rules: %v", err)
|
return fmt.Errorf("failed to update firewall rules: %v", err)
|
||||||
}
|
}
|
||||||
|
// Invalidate cache for old service name
|
||||||
|
s.apiService.statusCache.InvalidateStatus(existingServer.ServiceName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update database record
|
// Update database record
|
||||||
|
|||||||
Reference in New Issue
Block a user