github.com/TeaOSLab/EdgeNode@v1.3.8/internal/utils/agents/manager.go (about) 1 // Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn . 2 3 package agents 4 5 import ( 6 "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" 7 teaconst "github.com/TeaOSLab/EdgeNode/internal/const" 8 "github.com/TeaOSLab/EdgeNode/internal/events" 9 "github.com/TeaOSLab/EdgeNode/internal/goman" 10 "github.com/TeaOSLab/EdgeNode/internal/remotelogs" 11 "github.com/TeaOSLab/EdgeNode/internal/rpc" 12 "github.com/iwind/TeaGo/Tea" 13 "os" 14 "sync" 15 "time" 16 ) 17 18 var SharedManager = NewManager() 19 20 func init() { 21 if !teaconst.IsMain { 22 return 23 } 24 25 events.On(events.EventLoaded, func() { 26 goman.New(func() { 27 SharedManager.Start() 28 }) 29 }) 30 } 31 32 // Manager Agent管理器 33 type Manager struct { 34 ipMap map[string]string // ip => agentCode 35 locker sync.RWMutex 36 37 db DB 38 39 lastId int64 40 } 41 42 func NewManager() *Manager { 43 return &Manager{ 44 ipMap: map[string]string{}, 45 } 46 } 47 48 func (this *Manager) SetDB(db DB) { 49 this.db = db 50 } 51 52 func (this *Manager) Start() { 53 remotelogs.Println("AGENT_MANAGER", "starting ...") 54 55 err := this.loadDB() 56 if err != nil { 57 remotelogs.Error("AGENT_MANAGER", "load database failed: "+err.Error()) 58 return 59 } 60 61 // 从本地数据库中加载 62 err = this.Load() 63 if err != nil { 64 remotelogs.Error("AGENT_MANAGER", "load failed: "+err.Error()) 65 } 66 67 // 先从API获取 68 err = this.LoopAll() 69 if err != nil { 70 if rpc.IsConnError(err) { 71 remotelogs.Debug("AGENT_MANAGER", "retrieve latest agent ip failed: "+err.Error()) 72 } else { 73 remotelogs.Error("AGENT_MANAGER", "retrieve latest agent ip failed: "+err.Error()) 74 } 75 } 76 77 // 定时获取 78 var duration = 30 * time.Minute 79 if Tea.IsTesting() { 80 duration = 30 * time.Second 81 } 82 var ticker = time.NewTicker(duration) 83 for range ticker.C { 84 err = this.LoopAll() 85 if err != nil { 86 remotelogs.Error("AGENT_MANAGER", "retrieve latest agent ip failed: "+err.Error()) 87 } 88 } 89 } 90 91 func (this *Manager) Load() error { 92 var offset int64 = 0 93 var size int64 = 10000 94 for { 95 agentIPs, err := this.db.ListAgentIPs(offset, size) 96 if err != nil { 97 return err 98 } 99 if len(agentIPs) == 0 { 100 break 101 } 102 for _, agentIP := range agentIPs { 103 this.locker.Lock() 104 this.ipMap[agentIP.IP] = agentIP.AgentCode 105 this.locker.Unlock() 106 107 if agentIP.Id > this.lastId { 108 this.lastId = agentIP.Id 109 } 110 } 111 offset += size 112 } 113 114 return nil 115 } 116 117 func (this *Manager) LoopAll() error { 118 for { 119 hasNext, err := this.Loop() 120 if err != nil { 121 return err 122 } 123 if !hasNext { 124 break 125 } 126 } 127 return nil 128 } 129 130 // Loop 单次循环获取数据 131 func (this *Manager) Loop() (hasNext bool, err error) { 132 rpcClient, err := rpc.SharedRPC() 133 if err != nil { 134 return false, err 135 } 136 ipsResp, err := rpcClient.ClientAgentIPRPC.ListClientAgentIPsAfterId(rpcClient.Context(), &pb.ListClientAgentIPsAfterIdRequest{ 137 Id: this.lastId, 138 Size: 10000, 139 }) 140 if err != nil { 141 return false, err 142 } 143 if len(ipsResp.ClientAgentIPs) == 0 { 144 return false, nil 145 } 146 for _, agentIP := range ipsResp.ClientAgentIPs { 147 if agentIP.ClientAgent == nil { 148 // 设置ID 149 if agentIP.Id > this.lastId { 150 this.lastId = agentIP.Id 151 } 152 153 continue 154 } 155 156 // 写入到数据库 157 err = this.db.InsertAgentIP(agentIP.Id, agentIP.Ip, agentIP.ClientAgent.Code) 158 if err != nil { 159 return false, err 160 } 161 162 // 写入Map 163 this.locker.Lock() 164 this.ipMap[agentIP.Ip] = agentIP.ClientAgent.Code 165 this.locker.Unlock() 166 167 // 设置ID 168 if agentIP.Id > this.lastId { 169 this.lastId = agentIP.Id 170 } 171 } 172 173 return true, nil 174 } 175 176 // AddIP 添加记录 177 func (this *Manager) AddIP(ip string, agentCode string) { 178 this.locker.Lock() 179 this.ipMap[ip] = agentCode 180 this.locker.Unlock() 181 } 182 183 // LookupIP 查询IP所属Agent 184 func (this *Manager) LookupIP(ip string) (agentCode string) { 185 this.locker.RLock() 186 defer this.locker.RUnlock() 187 return this.ipMap[ip] 188 } 189 190 // ContainsIP 检查是否有IP相关数据 191 func (this *Manager) ContainsIP(ip string) bool { 192 this.locker.RLock() 193 defer this.locker.RUnlock() 194 _, ok := this.ipMap[ip] 195 return ok 196 } 197 198 func (this *Manager) loadDB() error { 199 var sqlitePath = Tea.Root + "/data/agents.db" 200 _, sqliteErr := os.Stat(sqlitePath) 201 var db DB 202 if sqliteErr == nil || !teaconst.EnableKVCacheStore { 203 db = NewSQLiteDB(sqlitePath) 204 } else { 205 db = NewKVDB() 206 } 207 err := db.Init() 208 if err != nil { 209 return err 210 } 211 this.db = db 212 return nil 213 }