improve: server list lock
Some checks are pending
CodeQL / Analyze (go) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
Contributors / contributors (push) Waiting to run
Sync / sync-to-jihulab (push) Waiting to run
Run Tests / tests (macos) (push) Waiting to run
Run Tests / tests (ubuntu) (push) Waiting to run
Run Tests / tests (windows) (push) Waiting to run

This commit is contained in:
naiba 2025-01-04 01:10:16 +08:00
parent efdae906c2
commit 81a08a38da
2 changed files with 25 additions and 21 deletions

View File

@ -85,7 +85,8 @@ func listServiceHistory(c *gin.Context) ([]*model.ServiceInfos, error) {
singleton.ServerLock.RLock()
server, ok := singleton.ServerList[id]
if !ok {
singleton.ServerLock.RUnlock()
if !ok || server == nil {
return nil, singleton.Localizer.ErrorT("server not found")
}
@ -95,7 +96,6 @@ func listServiceHistory(c *gin.Context) ([]*model.ServiceInfos, error) {
if server.HideForGuest && !authorized {
return nil, singleton.Localizer.ErrorT("unauthorized")
}
singleton.ServerLock.RUnlock()
var serviceHistories []*model.ServiceHistory
if err := singleton.DB.Model(&model.ServiceHistory{}).Select("service_id, created_at, server_id, avg_delay").

View File

@ -103,20 +103,20 @@ func (s *NezhaHandler) ReportSystemState(stream pb.NezhaService_ReportSystemStat
state := model.PB2State(state)
singleton.ServerLock.RLock()
if singleton.ServerList[clientID] == nil {
server, ok := singleton.ServerList[clientID]
singleton.ServerLock.RUnlock()
if !ok || server == nil {
return nil
}
singleton.ServerList[clientID].LastActive = time.Now()
singleton.ServerList[clientID].State = &state
server.LastActive = time.Now()
server.State = &state
// 应对 dashboard 重启的情况,如果从未记录过,先打点,等到小时时间点时入库
if singleton.ServerList[clientID].PrevTransferInSnapshot == 0 || singleton.ServerList[clientID].PrevTransferOutSnapshot == 0 {
singleton.ServerList[clientID].PrevTransferInSnapshot = int64(state.NetInTransfer)
singleton.ServerList[clientID].PrevTransferOutSnapshot = int64(state.NetOutTransfer)
if server.PrevTransferInSnapshot == 0 || server.PrevTransferOutSnapshot == 0 {
server.PrevTransferInSnapshot = int64(state.NetInTransfer)
server.PrevTransferOutSnapshot = int64(state.NetOutTransfer)
}
singleton.ServerLock.RUnlock()
stream.Send(&pb.Receipt{Proced: true})
}
@ -129,6 +129,7 @@ func (s *NezhaHandler) onReportSystemInfo(c context.Context, r *pb.Host) error {
return err
}
host := model.PB2Host(r)
singleton.ServerLock.RLock()
defer singleton.ServerLock.RUnlock()
@ -214,12 +215,18 @@ func (s *NezhaHandler) ReportGeoIP(c context.Context, r *pb.GeoIP) (*pb.GeoIP, e
joinedIP := geoip.IP.Join()
singleton.ServerLock.RLock()
server, ok := singleton.ServerList[clientID]
singleton.ServerLock.RUnlock()
if !ok || server == nil {
return nil, fmt.Errorf("server not found")
}
// 检查并更新DDNS
if singleton.ServerList[clientID].EnableDDNS && joinedIP != "" &&
(singleton.ServerList[clientID].GeoIP == nil || singleton.ServerList[clientID].GeoIP.IP != geoip.IP) {
if server.EnableDDNS && joinedIP != "" &&
(server.GeoIP == nil || server.GeoIP.IP != geoip.IP) {
ipv4 := geoip.IP.IPv4Addr
ipv6 := geoip.IP.IPv6Addr
providers, err := singleton.GetDDNSProvidersFromProfiles(singleton.ServerList[clientID].DDNSProfiles, &ddns.IP{Ipv4Addr: ipv4, Ipv6Addr: ipv6})
providers, err := singleton.GetDDNSProvidersFromProfiles(server.DDNSProfiles, &ddns.IP{Ipv4Addr: ipv4, Ipv6Addr: ipv6})
if err == nil {
for _, provider := range providers {
go func(provider *ddns.Provider) {
@ -232,23 +239,22 @@ func (s *NezhaHandler) ReportGeoIP(c context.Context, r *pb.GeoIP) (*pb.GeoIP, e
}
// 发送IP变动通知
if singleton.ServerList[clientID].GeoIP != nil && singleton.Conf.EnableIPChangeNotification &&
if server.GeoIP != nil && singleton.Conf.EnableIPChangeNotification &&
((singleton.Conf.Cover == model.ConfigCoverAll && !singleton.Conf.IgnoredIPNotificationServerIDs[clientID]) ||
(singleton.Conf.Cover == model.ConfigCoverIgnoreAll && singleton.Conf.IgnoredIPNotificationServerIDs[clientID])) &&
singleton.ServerList[clientID].GeoIP.IP.Join() != "" &&
server.GeoIP.IP.Join() != "" &&
joinedIP != "" &&
singleton.ServerList[clientID].GeoIP.IP != geoip.IP {
server.GeoIP.IP != geoip.IP {
singleton.SendNotification(singleton.Conf.IPChangeNotificationGroupID,
fmt.Sprintf(
"[%s] %s, %s => %s",
singleton.Localizer.T("IP Changed"),
singleton.ServerList[clientID].Name, singleton.IPDesensitize(singleton.ServerList[clientID].GeoIP.IP.Join()),
server.Name, singleton.IPDesensitize(server.GeoIP.IP.Join()),
singleton.IPDesensitize(joinedIP),
),
nil)
}
singleton.ServerLock.RUnlock()
// 根据内置数据库查询 IP 地理位置
var ip string
@ -266,9 +272,7 @@ func (s *NezhaHandler) ReportGeoIP(c context.Context, r *pb.GeoIP) (*pb.GeoIP, e
geoip.CountryCode = location
// 将地区码写入到 Host
singleton.ServerLock.Lock()
defer singleton.ServerLock.Unlock()
singleton.ServerList[clientID].GeoIP = &geoip
server.GeoIP = &geoip
return &pb.GeoIP{Ip: nil, CountryCode: location}, nil
}