- Renamed ListRobots function to ListAllRobots for clarity and consistency across the codebase. - Updated related API endpoints and tests to reflect the new function name. - Improved caching logic to ensure both autonomous and non-autonomous robots are loaded correctly. - Enhanced filtering and pagination capabilities within the ListAllRobots function. - Added new test cases to validate the updated functionality and ensure robust performance.
150 lines
3.1 KiB
Go
150 lines
3.1 KiB
Go
package cache
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/yaoapp/yao/agent/robot/types"
|
|
)
|
|
|
|
// RefreshConfig holds refresh configuration
|
|
type RefreshConfig struct {
|
|
Interval time.Duration // full refresh interval (default: 1 hour)
|
|
}
|
|
|
|
// DefaultRefreshConfig returns default refresh configuration
|
|
func DefaultRefreshConfig() *RefreshConfig {
|
|
return &RefreshConfig{
|
|
Interval: time.Hour,
|
|
}
|
|
}
|
|
|
|
// refreshState holds the refresh goroutine state
|
|
type refreshState struct {
|
|
ticker *time.Ticker
|
|
done chan struct{}
|
|
mu sync.Mutex
|
|
}
|
|
|
|
var refresher = &refreshState{}
|
|
|
|
// Refresh refreshes a single robot's config from database
|
|
func (c *Cache) Refresh(ctx *types.Context, memberID string) error {
|
|
robot, err := c.LoadByID(ctx, memberID)
|
|
if err != nil {
|
|
// If robot not found, remove from cache
|
|
if err == types.ErrRobotNotFound {
|
|
c.Remove(memberID)
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
|
|
// Update cache
|
|
c.Add(robot)
|
|
return nil
|
|
}
|
|
|
|
// StartAutoRefresh starts periodic full refresh
|
|
func (c *Cache) StartAutoRefresh(ctx *types.Context, config *RefreshConfig) {
|
|
if config == nil {
|
|
config = DefaultRefreshConfig()
|
|
}
|
|
|
|
refresher.mu.Lock()
|
|
defer refresher.mu.Unlock()
|
|
|
|
// Stop existing refresher if any
|
|
if refresher.done != nil {
|
|
close(refresher.done)
|
|
}
|
|
|
|
refresher.ticker = time.NewTicker(config.Interval)
|
|
refresher.done = make(chan struct{})
|
|
|
|
go func() {
|
|
for {
|
|
select {
|
|
case <-refresher.done:
|
|
refresher.ticker.Stop()
|
|
return
|
|
case <-refresher.ticker.C:
|
|
// Perform full refresh
|
|
_ = c.Load(ctx)
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
// StopAutoRefresh stops the periodic refresh
|
|
func (c *Cache) StopAutoRefresh() {
|
|
refresher.mu.Lock()
|
|
defer refresher.mu.Unlock()
|
|
|
|
if refresher.done != nil {
|
|
close(refresher.done)
|
|
refresher.done = nil
|
|
}
|
|
}
|
|
|
|
// RefreshAll reloads all robots from database
|
|
func (c *Cache) RefreshAll(ctx *types.Context) error {
|
|
return c.Load(ctx)
|
|
}
|
|
|
|
// Count returns the number of cached robots
|
|
func (c *Cache) Count() int {
|
|
c.mu.RLock()
|
|
defer c.mu.RUnlock()
|
|
return len(c.robots)
|
|
}
|
|
|
|
// ListAll returns all cached robots (across all teams)
|
|
func (c *Cache) ListAll() []*types.Robot {
|
|
c.mu.RLock()
|
|
defer c.mu.RUnlock()
|
|
|
|
robots := make([]*types.Robot, 0, len(c.robots))
|
|
for _, robot := range c.robots {
|
|
robots = append(robots, robot)
|
|
}
|
|
return robots
|
|
}
|
|
|
|
// ListAutonomous returns all cached robots with AutonomousMode=true.
|
|
func (c *Cache) ListAutonomous() []*types.Robot {
|
|
c.mu.RLock()
|
|
defer c.mu.RUnlock()
|
|
|
|
robots := make([]*types.Robot, 0, len(c.robots)/2)
|
|
for _, r := range c.robots {
|
|
if r.AutonomousMode {
|
|
robots = append(robots, r)
|
|
}
|
|
}
|
|
return robots
|
|
}
|
|
|
|
// GetByStatus returns robots with the specified status
|
|
func (c *Cache) GetByStatus(status types.RobotStatus) []*types.Robot {
|
|
c.mu.RLock()
|
|
defer c.mu.RUnlock()
|
|
|
|
var robots []*types.Robot
|
|
for _, robot := range c.robots {
|
|
if robot.Status == status {
|
|
robots = append(robots, robot)
|
|
}
|
|
}
|
|
return robots
|
|
}
|
|
|
|
// GetIdle returns all idle robots ready to execute
|
|
func (c *Cache) GetIdle() []*types.Robot {
|
|
return c.GetByStatus(types.RobotIdle)
|
|
}
|
|
|
|
// GetWorking returns all currently working robots
|
|
func (c *Cache) GetWorking() []*types.Robot {
|
|
return c.GetByStatus(types.RobotWorking)
|
|
}
|