mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-09-19 09:40:12 +00:00
feat: server transfer rotation
This commit is contained in:
+23
-2
@@ -6,6 +6,7 @@ import (
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -37,8 +38,21 @@ func (c *Common) GetID() uint64 {
|
||||
return c.ID
|
||||
}
|
||||
|
||||
// GetUserID 原子读取所属用户 ID。Server.UserID 会在 ServerTransfer 的
|
||||
// Register/revertTransition 流程里被实时改写以反映新所有者,同时 auth
|
||||
// 热路径在每次 agent RPC 都会读它。任何并发读必须走 atomic,否则与 SetUserID
|
||||
// 一起会被 go race detector 识别为 data race(见
|
||||
// TestServerUserIDConcurrentAccessIsRaceFree)。
|
||||
func (c *Common) GetUserID() uint64 {
|
||||
return c.UserID
|
||||
return atomic.LoadUint64(&c.UserID)
|
||||
}
|
||||
|
||||
// SetUserID 原子改写所属用户 ID。仅在「server 已经在 in-memory cache 里」
|
||||
// 的写入路径(ServerTransfer.Register / revertTransition)需要用 atomic
|
||||
// 保证可见性;普通 GORM AfterFind / Create 因为没有并发读所以可以直接赋
|
||||
// 值。配合 GetUserID 形成 atomic-only 的并发访问协议。
|
||||
func (c *Common) SetUserID(uid uint64) {
|
||||
atomic.StoreUint64(&c.UserID, uid)
|
||||
}
|
||||
|
||||
func (c *Common) HasPermission(ctx *gin.Context) bool {
|
||||
@@ -52,7 +66,14 @@ func (c *Common) HasPermission(ctx *gin.Context) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
return user.ID == c.UserID
|
||||
// 必须走 GetUserID 而不是裸读 c.UserID — Server.UserID 在
|
||||
// ServerTransfer.Register / revertTransition 里会被 atomic.StoreUint64
|
||||
// 改写,dashboard 各 controller 在 listHandler post-filter 这条热路径上
|
||||
// 高频对同一 *Server 调 HasPermission。裸读会与 SetUserID 形成 data
|
||||
// race(TestCommonHasPermissionConcurrentWithSetUserIDIsRaceFree 在
|
||||
// -race 下钉死该不变量),并且在 transfer 切换瞬间可能给出错误的权限
|
||||
// 判断。
|
||||
return user.ID == c.GetUserID()
|
||||
}
|
||||
|
||||
type CommonInterface interface {
|
||||
|
||||
Reference in New Issue
Block a user