mirror of
https://github.com/cubefs/cubefs.git
synced 2026-08-02 02:00:56 +00:00
feat(master): support config decommission settings
Signed-off-by: NaturalSelect <huangzhibin1@oppo.com>
This commit is contained in:
parent
8386685205
commit
5365949f7c
@ -253,7 +253,10 @@ func newClusterSetParasCmd(client *master.MasterClient) *cobra.Command {
|
||||
dataNodeSelector := ""
|
||||
metaNodeSelector := ""
|
||||
markBrokenDiskThreshold := ""
|
||||
autoDecommissionDisk := ""
|
||||
autoDecommissionDiskInterval := ""
|
||||
autoDpMetaRepair := ""
|
||||
autoDpMetaRepairParallelCnt := ""
|
||||
opMaxMpCntLimit := ""
|
||||
dpRepairTimeout := ""
|
||||
dpTimeout := ""
|
||||
@ -273,11 +276,36 @@ func newClusterSetParasCmd(client *master.MasterClient) *cobra.Command {
|
||||
}
|
||||
markBrokenDiskThreshold = fmt.Sprintf("%v", val)
|
||||
}
|
||||
|
||||
if autoDecommissionDisk != "" {
|
||||
if _, err = strconv.ParseBool(autoDecommissionDisk); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if autoDecommissionDiskInterval != "" {
|
||||
var interval time.Duration
|
||||
interval, err = time.ParseDuration(autoDecommissionDiskInterval)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if interval < time.Second {
|
||||
err = fmt.Errorf("auto decommission disk interval %v smaller than 1s", interval)
|
||||
return
|
||||
}
|
||||
|
||||
autoDecommissionDiskInterval = strconv.FormatInt(int64(interval), 10)
|
||||
}
|
||||
|
||||
if autoDpMetaRepair != "" {
|
||||
if _, err = strconv.ParseBool(autoDpMetaRepair); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if autoDpMetaRepairParallelCnt != "" {
|
||||
if _, err = strconv.ParseInt(autoDpMetaRepairParallelCnt, 10, 64); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if dpRepairTimeout != "" {
|
||||
var repairTimeout time.Duration
|
||||
@ -308,7 +336,10 @@ func newClusterSetParasCmd(client *master.MasterClient) *cobra.Command {
|
||||
if err = client.AdminAPI().SetClusterParas(optDelBatchCount, optMarkDeleteRate, optDelWorkerSleepMs,
|
||||
optAutoRepairRate, optLoadFactor, opMaxDpCntLimit, opMaxMpCntLimit, clientIDKey,
|
||||
dataNodesetSelector, metaNodesetSelector,
|
||||
dataNodeSelector, metaNodeSelector, markBrokenDiskThreshold, autoDpMetaRepair, dpRepairTimeout, dpTimeout); err != nil {
|
||||
dataNodeSelector, metaNodeSelector, markBrokenDiskThreshold,
|
||||
autoDecommissionDisk, autoDecommissionDiskInterval,
|
||||
autoDpMetaRepair, autoDpMetaRepairParallelCnt,
|
||||
dpRepairTimeout, dpTimeout); err != nil {
|
||||
return
|
||||
}
|
||||
stdout("Cluster parameters has been set successfully. \n")
|
||||
@ -328,8 +359,11 @@ func newClusterSetParasCmd(client *master.MasterClient) *cobra.Command {
|
||||
cmd.Flags().StringVar(&metaNodeSelector, CliFlagMetaNodeSelector, "", "Set the node select policy(metanode) for cluster")
|
||||
cmd.Flags().StringVar(&markBrokenDiskThreshold, CliFlagMarkDiskBrokenThreshold, "", "Threshold to mark disk as broken")
|
||||
cmd.Flags().StringVar(&autoDpMetaRepair, CliFlagAutoDpMetaRepair, "", "Enable or disable auto data partition meta repair")
|
||||
cmd.Flags().StringVar(&autoDpMetaRepairParallelCnt, CliFlagAutoDpMetaRepairParallelCnt, "", "Parallel count of auto data partition meta repair")
|
||||
cmd.Flags().StringVar(&dpRepairTimeout, CliFlagDpRepairTimeout, "", "Data partition repair timeout(example: 1h)")
|
||||
cmd.Flags().StringVar(&dpTimeout, CliFlagDpTimeout, "", "Data partition heartbeat timeout(example: 10s)")
|
||||
cmd.Flags().StringVar(&autoDecommissionDisk, CliFlagAutoDecommissionDisk, "", "Enable od disable auto decommission disk")
|
||||
cmd.Flags().StringVar(&autoDecommissionDiskInterval, CliFlagAutoDecommissionDiskInterval, "", "Interval of auto decommission disk(example: 10s)")
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
@ -135,8 +135,11 @@ const (
|
||||
CliFlagForce = "force"
|
||||
CliFlagEnableCrossZone = "cross-zone"
|
||||
CliFlagAutoDpMetaRepair = "autoDpMetaRepair"
|
||||
CliFlagAutoDpMetaRepairParallelCnt = "autoDpMetaRepairParallelCnt"
|
||||
CliFlagDpRepairTimeout = "dpRepairTimeout"
|
||||
CliFlagDpTimeout = "dpTimeout"
|
||||
CliFlagAutoDecommissionDisk = "autoDecommissionDisk"
|
||||
CliFlagAutoDecommissionDiskInterval = "autoDecommissionDiskInterval"
|
||||
|
||||
// CliFlagSetDataPartitionCount = "count" use dp-count instead
|
||||
|
||||
|
||||
@ -72,10 +72,12 @@ func formatClusterView(cv *proto.ClusterView, cn *proto.ClusterNodeInfo, cp *pro
|
||||
sb.WriteString(fmt.Sprintf(" DpRepairTimeout : %v\n", cv.DpRepairTimeout))
|
||||
sb.WriteString(fmt.Sprintf(" DataPartitionTimeout : %v\n", cv.DpTimeout))
|
||||
sb.WriteString(fmt.Sprintf(" volDeletionDelayTime : %v h\n", cv.VolDeletionDelayTimeHour))
|
||||
sb.WriteString(fmt.Sprintf(" EnableAutoDecommission: %v\n", cv.EnableAutoDecommission))
|
||||
sb.WriteString(fmt.Sprintf(" EnableAutoDpMetaRepair: %v\n", cv.EnableAutoDpMetaRepair))
|
||||
sb.WriteString(fmt.Sprintf(" EnableAutoDecommission : %v\n", cv.EnableAutoDecommission))
|
||||
sb.WriteString(fmt.Sprintf(" AutoDecommissionDiskIntervak : %v\n", cv.AutoDecommissionDiskInterval))
|
||||
sb.WriteString(fmt.Sprintf(" EnableAutoDpMetaRepair : %v\n", cv.EnableAutoDpMetaRepair))
|
||||
sb.WriteString(fmt.Sprintf(" AutoDpMetaRepairParallelCnt : %v\n", cv.AutoDpMetaRepairParallelCnt))
|
||||
sb.WriteString(fmt.Sprintf(" MarkDiskBrokenThreshold : %v\n", strutil.FormatPercent(cv.MarkDiskBrokenThreshold)))
|
||||
sb.WriteString(fmt.Sprintf(" DecommissionDiskLimit: %v\n", cv.DecommissionDiskLimit))
|
||||
sb.WriteString(fmt.Sprintf(" DecommissionDiskLimit : %v\n", cv.DecommissionDiskLimit))
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
|
||||
@ -1329,6 +1329,28 @@ func parseAndExtractSetNodeInfoParams(r *http.Request) (params map[string]interf
|
||||
params[markDiskBrokenThresholdKey] = val
|
||||
}
|
||||
|
||||
if value = r.FormValue(autoDecommissionDiskKey); value != "" {
|
||||
noParams = false
|
||||
val := false
|
||||
val, err = strconv.ParseBool(value)
|
||||
if err != nil {
|
||||
err = unmatchedKey(autoDecommissionDiskKey)
|
||||
return
|
||||
}
|
||||
params[autoDecommissionDiskKey] = val
|
||||
}
|
||||
|
||||
if value = r.FormValue(autoDecommissionDiskIntervalKey); value != "" {
|
||||
noParams = false
|
||||
val := int64(0)
|
||||
val, err = strconv.ParseInt(value, 10, 64)
|
||||
if err != nil {
|
||||
err = unmatchedKey(autoDecommissionDiskIntervalKey)
|
||||
return
|
||||
}
|
||||
params[autoDecommissionDiskIntervalKey] = time.Duration(val)
|
||||
}
|
||||
|
||||
if value = r.FormValue(autoDpMetaRepairKey); value != "" {
|
||||
noParams = false
|
||||
val := false
|
||||
@ -1340,6 +1362,17 @@ func parseAndExtractSetNodeInfoParams(r *http.Request) (params map[string]interf
|
||||
params[autoDpMetaRepairKey] = val
|
||||
}
|
||||
|
||||
if value = r.FormValue(autoDpMetaRepairParallelCntKey); value != "" {
|
||||
noParams = false
|
||||
val := int64(0)
|
||||
val, err = strconv.ParseInt(value, 10, 32)
|
||||
if err != nil {
|
||||
err = unmatchedKey(autoDpMetaRepairParallelCntKey)
|
||||
return
|
||||
}
|
||||
params[autoDpMetaRepairParallelCntKey] = int(val)
|
||||
}
|
||||
|
||||
if value = r.FormValue(dpTimeoutKey); value != "" {
|
||||
noParams = false
|
||||
val := int64(0)
|
||||
|
||||
@ -797,7 +797,9 @@ func (m *Server) getCluster(w http.ResponseWriter, r *http.Request) {
|
||||
DpRepairTimeout: m.cluster.GetDecommissionDataPartitionRecoverTimeOut(),
|
||||
MarkDiskBrokenThreshold: m.cluster.getMarkDiskBrokenThreshold(),
|
||||
EnableAutoDpMetaRepair: m.cluster.getEnableAutoDpMetaRepair(),
|
||||
AutoDpMetaRepairParallelCnt: m.cluster.GetAutoDpMetaRepairParallelCnt(),
|
||||
EnableAutoDecommission: m.cluster.AutoDecommissionDiskIsEnabled(),
|
||||
AutoDecommissionDiskInterval: m.cluster.GetAutoDecommissionDiskInterval(),
|
||||
DecommissionDiskLimit: m.cluster.GetDecommissionDiskLimit(),
|
||||
DpTimeout: time.Duration(m.cluster.getDataPartitionTimeoutSec()) * time.Second,
|
||||
MasterNodes: make([]proto.NodeView, 0),
|
||||
@ -3160,6 +3162,27 @@ func (m *Server) setNodeInfoHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := params[autoDecommissionDiskKey]; ok {
|
||||
if autoDecomm, ok := val.(bool); ok {
|
||||
old := m.cluster.EnableAutoDecommissionDisk.Load()
|
||||
m.cluster.EnableAutoDecommissionDisk.Store(autoDecomm)
|
||||
if err = m.cluster.syncPutCluster(); err != nil {
|
||||
m.cluster.EnableAutoDecommissionDisk.Store(old)
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := params[autoDecommissionDiskIntervalKey]; ok {
|
||||
if interval, ok := val.(time.Duration); ok {
|
||||
if err = m.cluster.setAutoDecommissionDiskInterval(interval); err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := params[autoDpMetaRepairKey]; ok {
|
||||
if autoRepair, ok := val.(bool); ok {
|
||||
if err = m.cluster.setEnableAutoDpMetaRepair(autoRepair); err != nil {
|
||||
@ -3169,6 +3192,15 @@ func (m *Server) setNodeInfoHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := params[autoDpMetaRepairParallelCntKey]; ok {
|
||||
if cnt, ok := val.(int); ok {
|
||||
if err = m.cluster.setAutoDpMetaRepairParallelCnt(cnt); err != nil {
|
||||
sendErrReply(w, r, newErrHTTPReply(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := params[dpTimeoutKey]; ok {
|
||||
if dpTimeout, ok := val.(int64); ok {
|
||||
if err = m.cluster.setDataPartitionTimeout(dpTimeout); err != nil {
|
||||
|
||||
@ -1645,6 +1645,30 @@ func TestSetMarkDiskBrokenThreshold(t *testing.T) {
|
||||
require.EqualValues(t, oldVal, server.cluster.getMarkDiskBrokenThreshold())
|
||||
}
|
||||
|
||||
func TestSetEnableAutoDecommissionDisk(t *testing.T) {
|
||||
reqUrl := fmt.Sprintf("%v%v", hostAddr, proto.AdminSetNodeInfo)
|
||||
oldVal := server.cluster.EnableAutoDecommissionDisk.Load()
|
||||
setVal := !oldVal
|
||||
setUrl := fmt.Sprintf("%v?%v=%v&dirSizeLimit=0", reqUrl, autoDecommissionDiskKey, setVal)
|
||||
unsetUrl := fmt.Sprintf("%v?%v=%v&dirSizeLimit=0", reqUrl, autoDecommissionDiskKey, oldVal)
|
||||
process(setUrl, t)
|
||||
require.EqualValues(t, setVal, server.cluster.EnableAutoDecommissionDisk.Load())
|
||||
process(unsetUrl, t)
|
||||
require.EqualValues(t, oldVal, server.cluster.EnableAutoDecommissionDisk.Load())
|
||||
}
|
||||
|
||||
func TestSetDecommissionDiskInterval(t *testing.T) {
|
||||
reqUrl := fmt.Sprintf("%v%v", hostAddr, proto.AdminSetNodeInfo)
|
||||
oldVal := server.cluster.GetAutoDecommissionDiskInterval()
|
||||
setVal := oldVal + 10*time.Second
|
||||
setUrl := fmt.Sprintf("%v?%v=%v&dirSizeLimit=0", reqUrl, autoDecommissionDiskIntervalKey, int64(setVal))
|
||||
unsetUrl := fmt.Sprintf("%v?%v=%v&dirSizeLimit=0", reqUrl, autoDecommissionDiskIntervalKey, int64(oldVal))
|
||||
process(setUrl, t)
|
||||
require.EqualValues(t, setVal, server.cluster.GetAutoDecommissionDiskInterval())
|
||||
process(unsetUrl, t)
|
||||
require.EqualValues(t, oldVal, server.cluster.GetAutoDecommissionDiskInterval())
|
||||
}
|
||||
|
||||
func TestSetEnableAutoDpMetaRepair(t *testing.T) {
|
||||
reqUrl := fmt.Sprintf("%v%v", hostAddr, proto.AdminSetNodeInfo)
|
||||
oldVal := server.cluster.getEnableAutoDpMetaRepair()
|
||||
@ -1657,6 +1681,18 @@ func TestSetEnableAutoDpMetaRepair(t *testing.T) {
|
||||
require.EqualValues(t, oldVal, server.cluster.getEnableAutoDpMetaRepair())
|
||||
}
|
||||
|
||||
func TestSetAutoDpMetaRepairParallelCnt(t *testing.T) {
|
||||
reqUrl := fmt.Sprintf("%v%v", hostAddr, proto.AdminSetNodeInfo)
|
||||
oldVal := server.cluster.GetAutoDpMetaRepairParallelCnt()
|
||||
setVal := 200
|
||||
setUrl := fmt.Sprintf("%v?%v=%v&dirSizeLimit=0", reqUrl, autoDpMetaRepairParallelCntKey, setVal)
|
||||
unsetUrl := fmt.Sprintf("%v?%v=%v&dirSizeLimit=0", reqUrl, autoDpMetaRepairParallelCntKey, oldVal)
|
||||
process(setUrl, t)
|
||||
require.EqualValues(t, setVal, server.cluster.GetAutoDpMetaRepairParallelCnt())
|
||||
process(unsetUrl, t)
|
||||
require.EqualValues(t, oldVal, server.cluster.GetAutoDpMetaRepairParallelCnt())
|
||||
}
|
||||
|
||||
func TestSetDpTimeout(t *testing.T) {
|
||||
reqUrl := fmt.Sprintf("%v%v", hostAddr, proto.AdminSetNodeInfo)
|
||||
oldVal := server.cluster.getDataPartitionTimeoutSec()
|
||||
|
||||
@ -86,7 +86,8 @@ type Cluster struct {
|
||||
apiLimiter *ApiLimiter
|
||||
DecommissionDisks sync.Map
|
||||
DecommissionLimit uint64
|
||||
EnableAutoDecommissionDisk bool
|
||||
EnableAutoDecommissionDisk atomicutil.Bool
|
||||
AutoDecommissionInterval atomicutil.Int64
|
||||
AutoDecommissionDiskMux sync.Mutex
|
||||
checkAutoCreateDataPartition bool
|
||||
masterClient *masterSDK.MasterClient
|
||||
@ -106,6 +107,7 @@ type Cluster struct {
|
||||
S3ApiQosQuota *sync.Map // (api,uid,limtType) -> limitQuota
|
||||
MarkDiskBrokenThreshold atomicutil.Float64
|
||||
EnableAutoDpMetaRepair atomicutil.Bool
|
||||
AutoDpMetaRepairParallelCnt atomicutil.Uint32
|
||||
}
|
||||
|
||||
type delayDeleteVolInfo struct {
|
||||
@ -371,6 +373,7 @@ func newCluster(name string, leaderInfo *LeaderInfo, fsm *MetadataFsm, partition
|
||||
c.S3ApiQosQuota = new(sync.Map)
|
||||
c.MarkDiskBrokenThreshold.Store(defaultMarkDiskBrokenThreshold)
|
||||
c.EnableAutoDpMetaRepair.Store(defaultEnableDpMetaRepair)
|
||||
c.AutoDecommissionInterval.Store(int64(defaultAutoDecommissionDiskInterval))
|
||||
return
|
||||
}
|
||||
|
||||
@ -4257,7 +4260,7 @@ func (c *Cluster) scheduleToBadDisk() {
|
||||
if c.partition.IsRaftLeader() && c.AutoDecommissionDiskIsEnabled() && c.metaReady {
|
||||
c.checkBadDisk()
|
||||
}
|
||||
time.Sleep(10 * time.Second)
|
||||
time.Sleep(c.GetAutoDecommissionDiskInterval())
|
||||
}
|
||||
}()
|
||||
}
|
||||
@ -4916,13 +4919,50 @@ func (c *Cluster) addDecommissionDiskToNodeset(dd *DecommissionDisk) (err error)
|
||||
func (c *Cluster) AutoDecommissionDiskIsEnabled() bool {
|
||||
c.AutoDecommissionDiskMux.Lock()
|
||||
defer c.AutoDecommissionDiskMux.Unlock()
|
||||
return c.EnableAutoDecommissionDisk
|
||||
return c.EnableAutoDecommissionDisk.Load()
|
||||
}
|
||||
|
||||
func (c *Cluster) SetAutoDecommissionDisk(flag bool) {
|
||||
c.AutoDecommissionDiskMux.Lock()
|
||||
defer c.AutoDecommissionDiskMux.Unlock()
|
||||
c.EnableAutoDecommissionDisk = flag
|
||||
c.EnableAutoDecommissionDisk.Store(flag)
|
||||
}
|
||||
|
||||
func (c *Cluster) GetAutoDecommissionDiskInterval() (interval time.Duration) {
|
||||
tmp := c.AutoDecommissionInterval.Load()
|
||||
if tmp == 0 {
|
||||
tmp = int64(defaultAutoDecommissionDiskInterval)
|
||||
}
|
||||
interval = time.Duration(tmp)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Cluster) setAutoDecommissionDiskInterval(interval time.Duration) (err error) {
|
||||
old := c.AutoDecommissionInterval.Load()
|
||||
c.AutoDecommissionInterval.Store(int64(interval))
|
||||
if err = c.syncPutCluster(); err != nil {
|
||||
c.AutoDecommissionInterval.Store(old)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Cluster) GetAutoDpMetaRepairParallelCnt() (cnt int) {
|
||||
cnt = int(c.AutoDpMetaRepairParallelCnt.Load())
|
||||
if cnt == 0 {
|
||||
cnt = defaultAutoDpMetaRepairPallarelCnt
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Cluster) setAutoDpMetaRepairParallelCnt(cnt int) (err error) {
|
||||
old := c.AutoDpMetaRepairParallelCnt.Load()
|
||||
c.AutoDpMetaRepairParallelCnt.Store(uint32(cnt))
|
||||
if err = c.syncPutCluster(); err != nil {
|
||||
c.AutoDpMetaRepairParallelCnt.Store(old)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Cluster) GetDecommissionDataPartitionRecoverTimeOut() time.Duration {
|
||||
|
||||
@ -139,7 +139,10 @@ const (
|
||||
dpRepairBlockSizeKey = "dpRepairBlockSize"
|
||||
markDiskBrokenThresholdKey = "markDiskBrokenThreshold"
|
||||
decommissionTypeKey = "decommissionType"
|
||||
autoDecommissionDiskKey = "autoDecommissionDisk"
|
||||
autoDecommissionDiskIntervalKey = "autoDecommissionDiskInterval"
|
||||
autoDpMetaRepairKey = "autoDpMetaRepair"
|
||||
autoDpMetaRepairParallelCntKey = "autoDpMetaRepairParallelCnt"
|
||||
dpTimeoutKey = "dpTimeout"
|
||||
)
|
||||
|
||||
@ -214,6 +217,8 @@ const (
|
||||
defaultVolDelayDeleteTimeHour = 48
|
||||
defaultMarkDiskBrokenThreshold = 0 // decommission all dp from disk
|
||||
defaultEnableDpMetaRepair = false
|
||||
defaultAutoDpMetaRepairPallarelCnt = 100
|
||||
defaultAutoDecommissionDiskInterval = 10 * time.Second
|
||||
maxMpCreationCount = 10
|
||||
)
|
||||
|
||||
|
||||
@ -61,10 +61,12 @@ type clusterValue struct {
|
||||
DpMaxRepairErrCnt uint64
|
||||
DpRepairTimeOut uint64
|
||||
EnableAutoDecommissionDisk bool
|
||||
AutoDecommissionDiskInterval int64
|
||||
DecommissionDiskLimit uint32
|
||||
VolDeletionDelayTimeHour int64
|
||||
MarkDiskBrokenThreshold float64
|
||||
EnableAutoDpMetaRepair bool
|
||||
AutoDpMetaRepairParallelCnt uint32
|
||||
DataPartitionTimeoutSec int64
|
||||
}
|
||||
|
||||
@ -95,11 +97,13 @@ func newClusterValue(c *Cluster) (cv *clusterValue) {
|
||||
MaxConcurrentLcNodes: c.cfg.MaxConcurrentLcNodes,
|
||||
DpMaxRepairErrCnt: c.cfg.DpMaxRepairErrCnt,
|
||||
DpRepairTimeOut: c.cfg.DpRepairTimeOut,
|
||||
EnableAutoDecommissionDisk: c.EnableAutoDecommissionDisk,
|
||||
EnableAutoDecommissionDisk: c.EnableAutoDecommissionDisk.Load(),
|
||||
AutoDecommissionDiskInterval: c.AutoDecommissionInterval.Load(),
|
||||
DecommissionDiskLimit: c.GetDecommissionDiskLimit(),
|
||||
VolDeletionDelayTimeHour: c.cfg.volDelayDeleteTimeHour,
|
||||
MarkDiskBrokenThreshold: c.getMarkDiskBrokenThreshold(),
|
||||
EnableAutoDpMetaRepair: c.getEnableAutoDpMetaRepair(),
|
||||
AutoDpMetaRepairParallelCnt: c.AutoDpMetaRepairParallelCnt.Load(),
|
||||
DataPartitionTimeoutSec: c.getDataPartitionTimeoutSec(),
|
||||
}
|
||||
return cv
|
||||
@ -1057,6 +1061,14 @@ func (c *Cluster) updateEnableAutoDpMetaRepair(val bool) {
|
||||
c.EnableAutoDpMetaRepair.Store(val)
|
||||
}
|
||||
|
||||
func (c *Cluster) updateAutoDecommissionDiskInterval(val int64) {
|
||||
c.AutoDecommissionInterval.Store(val)
|
||||
}
|
||||
|
||||
func (c *Cluster) updateAutoDpMetaRepairParallelCnt(cnt uint32) {
|
||||
c.AutoDpMetaRepairParallelCnt.Store(cnt)
|
||||
}
|
||||
|
||||
func (c *Cluster) updateDecommissionDiskLimit(val uint32) {
|
||||
if val < 1 {
|
||||
val = 1
|
||||
@ -1179,7 +1191,8 @@ func (c *Cluster) loadClusterValue() (err error) {
|
||||
c.clusterUuid = cv.ClusterUuid
|
||||
c.clusterUuidEnable = cv.ClusterUuidEnable
|
||||
c.DecommissionLimit = cv.DecommissionLimit
|
||||
c.EnableAutoDecommissionDisk = cv.EnableAutoDecommissionDisk
|
||||
c.EnableAutoDecommissionDisk.Store(cv.EnableAutoDecommissionDisk)
|
||||
c.updateAutoDecommissionDiskInterval(cv.AutoDecommissionDiskInterval)
|
||||
c.DecommissionLimit = cv.DecommissionLimit
|
||||
c.cfg.volDelayDeleteTimeHour = cv.VolDeletionDelayTimeHour
|
||||
|
||||
@ -1213,6 +1226,7 @@ func (c *Cluster) loadClusterValue() (err error) {
|
||||
c.checkDataReplicasEnable = cv.CheckDataReplicasEnable
|
||||
c.updateMarkDiskBrokenThreshold(cv.MarkDiskBrokenThreshold)
|
||||
c.updateEnableAutoDpMetaRepair(cv.EnableAutoDpMetaRepair)
|
||||
c.updateAutoDpMetaRepairParallelCnt(cv.AutoDpMetaRepairParallelCnt)
|
||||
c.updateDataPartitionTimeoutSec(cv.DataPartitionTimeoutSec)
|
||||
}
|
||||
return
|
||||
|
||||
@ -607,7 +607,7 @@ func (vol *Vol) checkDataPartitions(c *Cluster) (cnt int) {
|
||||
|
||||
partitions := vol.dataPartitions.clonePartitions()
|
||||
checkMetaDp := make(map[uint64]*DataPartition)
|
||||
checkMetaPool := routinepool.NewRoutinePool(10)
|
||||
checkMetaPool := routinepool.NewRoutinePool(c.GetAutoDpMetaRepairParallelCnt())
|
||||
defer checkMetaPool.WaitAndClose()
|
||||
var checkMetaDpWg sync.WaitGroup
|
||||
|
||||
|
||||
@ -130,7 +130,9 @@ type ClusterView struct {
|
||||
VolDeletionDelayTimeHour int64
|
||||
MarkDiskBrokenThreshold float64
|
||||
EnableAutoDpMetaRepair bool
|
||||
AutoDpMetaRepairParallelCnt int
|
||||
EnableAutoDecommission bool
|
||||
AutoDecommissionDiskInterval time.Duration
|
||||
DecommissionDiskLimit uint32
|
||||
DpRepairTimeout time.Duration
|
||||
DpTimeout time.Duration
|
||||
|
||||
@ -517,7 +517,9 @@ func (api *AdminAPI) SetMasterVolDeletionDelayTime(volDeletionDelayTimeHour int)
|
||||
|
||||
func (api *AdminAPI) SetClusterParas(batchCount, markDeleteRate, deleteWorkerSleepMs, autoRepairRate, loadFactor, maxDpCntLimit, maxMpCntLimit, clientIDKey string,
|
||||
dataNodesetSelector, metaNodesetSelector, dataNodeSelector, metaNodeSelector string, markDiskBrokenThreshold string,
|
||||
enableAutoDpMetaRepair string, dpRepairTimeout string, dpTimeout string,
|
||||
enableAutoDecommissionDisk string, autoDecommissionDiskInterval string,
|
||||
enableAutoDpMetaRepair string, autoDpMetaRepairParallelCnt string,
|
||||
dpRepairTimeout string, dpTimeout string,
|
||||
) (err error) {
|
||||
request := newRequest(get, proto.AdminSetNodeInfo).Header(api.h)
|
||||
request.addParam("batchCount", batchCount)
|
||||
@ -536,9 +538,18 @@ func (api *AdminAPI) SetClusterParas(batchCount, markDeleteRate, deleteWorkerSle
|
||||
if markDiskBrokenThreshold != "" {
|
||||
request.addParam("markDiskBrokenThreshold", markDiskBrokenThreshold)
|
||||
}
|
||||
if enableAutoDecommissionDisk != "" {
|
||||
request.addParam("autoDecommissionDisk", enableAutoDecommissionDisk)
|
||||
}
|
||||
if autoDecommissionDiskInterval != "" {
|
||||
request.addParam("autoDecommissionDiskInterval", autoDecommissionDiskInterval)
|
||||
}
|
||||
if enableAutoDpMetaRepair != "" {
|
||||
request.addParam("autoDpMetaRepair", enableAutoDpMetaRepair)
|
||||
}
|
||||
if autoDpMetaRepairParallelCnt != "" {
|
||||
request.addParam("autoDpMetaRepairParallelCnt", autoDpMetaRepairParallelCnt)
|
||||
}
|
||||
if dpRepairTimeout != "" {
|
||||
request.addParam("dpRepairTimeOut", dpRepairTimeout)
|
||||
}
|
||||
|
||||
@ -45,3 +45,12 @@ func (b *Bool) CompareAndSwap(old bool, newVal bool) (swaped bool) {
|
||||
swaped = atomic.CompareAndSwapUint32(&b.val, oldVal, val)
|
||||
return
|
||||
}
|
||||
|
||||
func (b *Bool) Swap(new bool) (old bool) {
|
||||
tmp := uint32(0)
|
||||
if new {
|
||||
tmp = 1
|
||||
}
|
||||
old = atomic.SwapUint32(&b.val, tmp) == 1
|
||||
return
|
||||
}
|
||||
|
||||
@ -27,4 +27,6 @@ func TestAtomicBool(t *testing.T) {
|
||||
require.True(t, b.Load())
|
||||
require.True(t, b.CompareAndSwap(true, false))
|
||||
require.False(t, b.Load())
|
||||
require.False(t, b.Swap(true))
|
||||
require.True(t, b.Load())
|
||||
}
|
||||
|
||||
42
util/atomicutil/float32.go
Normal file
42
util/atomicutil/float32.go
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2023 The CubeFS Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package atomicutil
|
||||
|
||||
import (
|
||||
"math"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
type Float32 struct {
|
||||
val uint32
|
||||
}
|
||||
|
||||
func (f *Float32) Load() float32 {
|
||||
return math.Float32frombits(atomic.LoadUint32(&f.val))
|
||||
}
|
||||
|
||||
func (f *Float32) Store(val float32) {
|
||||
atomic.StoreUint32(&f.val, math.Float32bits(val))
|
||||
}
|
||||
|
||||
func (f *Float32) CompareAndSwap(old float32, new float32) (swaped bool) {
|
||||
swaped = atomic.CompareAndSwapUint32(&f.val, math.Float32bits(old), math.Float32bits(new))
|
||||
return
|
||||
}
|
||||
|
||||
func (f *Float32) Swap(new float32) (old float32) {
|
||||
old = math.Float32frombits(atomic.SwapUint32(&f.val, math.Float32bits(new)))
|
||||
return
|
||||
}
|
||||
32
util/atomicutil/float32_test.go
Normal file
32
util/atomicutil/float32_test.go
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright 2023 The CubeFS Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package atomicutil_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cubefs/cubefs/util/atomicutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAtomicFloat32(t *testing.T) {
|
||||
f := atomicutil.Float32{}
|
||||
testVal := float32(1.0)
|
||||
f.Store(testVal)
|
||||
require.Equal(t, testVal, f.Load())
|
||||
require.True(t, f.CompareAndSwap(testVal, 0))
|
||||
require.EqualValues(t, 0, f.Swap(testVal))
|
||||
require.EqualValues(t, testVal, f.Load())
|
||||
}
|
||||
@ -30,3 +30,13 @@ func (f *Float64) Load() float64 {
|
||||
func (f *Float64) Store(val float64) {
|
||||
atomic.StoreUint64(&f.val, math.Float64bits(val))
|
||||
}
|
||||
|
||||
func (f *Float64) CompareAndSwap(old float64, new float64) (swaped bool) {
|
||||
swaped = atomic.CompareAndSwapUint64(&f.val, math.Float64bits(old), math.Float64bits(new))
|
||||
return
|
||||
}
|
||||
|
||||
func (f *Float64) Swap(new float64) (old float64) {
|
||||
old = math.Float64frombits(atomic.SwapUint64(&f.val, math.Float64bits(new)))
|
||||
return
|
||||
}
|
||||
|
||||
@ -26,4 +26,7 @@ func TestAtomicFloat64(t *testing.T) {
|
||||
testVal := float64(1.0)
|
||||
f.Store(testVal)
|
||||
require.Equal(t, testVal, f.Load())
|
||||
require.True(t, f.CompareAndSwap(testVal, 0))
|
||||
require.EqualValues(t, 0, f.Swap(testVal))
|
||||
require.EqualValues(t, testVal, f.Load())
|
||||
}
|
||||
|
||||
50
util/atomicutil/int32.go
Normal file
50
util/atomicutil/int32.go
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright 2024 The CubeFS Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package atomicutil
|
||||
|
||||
import "sync/atomic"
|
||||
|
||||
type Int32 struct {
|
||||
v int32
|
||||
}
|
||||
|
||||
func (i *Int32) Load() (v int32) {
|
||||
v = atomic.LoadInt32(&i.v)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Int32) Store(v int32) {
|
||||
atomic.StoreInt32(&i.v, v)
|
||||
}
|
||||
|
||||
func (i *Int32) CompareAndSwap(old int32, new int32) (swaped bool) {
|
||||
swaped = atomic.CompareAndSwapInt32(&i.v, old, new)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Int32) Add(v int32) (new int32) {
|
||||
new = atomic.AddInt32(&i.v, v)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Int32) Sub(v int32) (new int32) {
|
||||
new = atomic.AddInt32(&i.v, -v)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Int32) Swap(v int32) (old int32) {
|
||||
old = atomic.SwapInt32(&i.v, v)
|
||||
return
|
||||
}
|
||||
33
util/atomicutil/int32_test.go
Normal file
33
util/atomicutil/int32_test.go
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2024 The CubeFS Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package atomicutil_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cubefs/cubefs/util/atomicutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestInt32(t *testing.T) {
|
||||
i := atomicutil.Int32{}
|
||||
i.Store(1)
|
||||
require.EqualValues(t, 1, i.Load())
|
||||
require.EqualValues(t, 2, i.Add(1))
|
||||
require.EqualValues(t, 2, i.Swap(1))
|
||||
require.True(t, i.CompareAndSwap(1, 2))
|
||||
require.EqualValues(t, 2, i.Load())
|
||||
require.EqualValues(t, 1, i.Sub(1))
|
||||
}
|
||||
50
util/atomicutil/int64.go
Normal file
50
util/atomicutil/int64.go
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright 2024 The CubeFS Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package atomicutil
|
||||
|
||||
import "sync/atomic"
|
||||
|
||||
type Int64 struct {
|
||||
v int64
|
||||
}
|
||||
|
||||
func (i *Int64) Load() (v int64) {
|
||||
v = atomic.LoadInt64(&i.v)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Int64) Store(v int64) {
|
||||
atomic.StoreInt64(&i.v, v)
|
||||
}
|
||||
|
||||
func (i *Int64) CompareAndSwap(old int64, new int64) (swaped bool) {
|
||||
swaped = atomic.CompareAndSwapInt64(&i.v, old, new)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Int64) Add(v int64) (new int64) {
|
||||
new = atomic.AddInt64(&i.v, v)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Int64) Sub(v int64) (new int64) {
|
||||
new = atomic.AddInt64(&i.v, -v)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Int64) Swap(v int64) (old int64) {
|
||||
old = atomic.SwapInt64(&i.v, v)
|
||||
return
|
||||
}
|
||||
33
util/atomicutil/int64_test.go
Normal file
33
util/atomicutil/int64_test.go
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2024 The CubeFS Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package atomicutil_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cubefs/cubefs/util/atomicutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestInt64(t *testing.T) {
|
||||
i := atomicutil.Int64{}
|
||||
i.Store(1)
|
||||
require.EqualValues(t, 1, i.Load())
|
||||
require.EqualValues(t, 2, i.Add(1))
|
||||
require.EqualValues(t, 2, i.Swap(1))
|
||||
require.True(t, i.CompareAndSwap(1, 2))
|
||||
require.EqualValues(t, 2, i.Load())
|
||||
require.EqualValues(t, 1, i.Sub(1))
|
||||
}
|
||||
50
util/atomicutil/uint32.go
Normal file
50
util/atomicutil/uint32.go
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright 2024 The CubeFS Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package atomicutil
|
||||
|
||||
import "sync/atomic"
|
||||
|
||||
type Uint32 struct {
|
||||
v uint32
|
||||
}
|
||||
|
||||
func (i *Uint32) Load() (v uint32) {
|
||||
v = atomic.LoadUint32(&i.v)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Uint32) Store(v uint32) {
|
||||
atomic.StoreUint32(&i.v, v)
|
||||
}
|
||||
|
||||
func (i *Uint32) CompareAndSwap(old uint32, new uint32) (swaped bool) {
|
||||
swaped = atomic.CompareAndSwapUint32(&i.v, old, new)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Uint32) Add(v uint32) (new uint32) {
|
||||
new = atomic.AddUint32(&i.v, v)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Uint32) Sub(v int32) (new uint32) {
|
||||
new = atomic.AddUint32(&i.v, ^uint32(v-1))
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Uint32) Swap(v uint32) (old uint32) {
|
||||
old = atomic.SwapUint32(&i.v, v)
|
||||
return
|
||||
}
|
||||
33
util/atomicutil/uint32_test.go
Normal file
33
util/atomicutil/uint32_test.go
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2024 The CubeFS Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package atomicutil_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cubefs/cubefs/util/atomicutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestUint64(t *testing.T) {
|
||||
i := atomicutil.Uint32{}
|
||||
i.Store(1)
|
||||
require.EqualValues(t, 1, i.Load())
|
||||
require.EqualValues(t, 2, i.Add(1))
|
||||
require.EqualValues(t, 2, i.Swap(1))
|
||||
require.True(t, i.CompareAndSwap(1, 2))
|
||||
require.EqualValues(t, 2, i.Load())
|
||||
require.EqualValues(t, 1, i.Sub(1))
|
||||
}
|
||||
50
util/atomicutil/uint64.go
Normal file
50
util/atomicutil/uint64.go
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright 2024 The CubeFS Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package atomicutil
|
||||
|
||||
import "sync/atomic"
|
||||
|
||||
type Uint64 struct {
|
||||
v uint64
|
||||
}
|
||||
|
||||
func (i *Uint64) Load() (v uint64) {
|
||||
v = atomic.LoadUint64(&i.v)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Uint64) Store(v uint64) {
|
||||
atomic.StoreUint64(&i.v, v)
|
||||
}
|
||||
|
||||
func (i *Uint64) CompareAndSwap(old uint64, new uint64) (swaped bool) {
|
||||
swaped = atomic.CompareAndSwapUint64(&i.v, old, new)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Uint64) Add(v uint64) (new uint64) {
|
||||
new = atomic.AddUint64(&i.v, v)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Uint64) Sub(v int64) (new uint64) {
|
||||
new = atomic.AddUint64(&i.v, ^uint64(v-1))
|
||||
return
|
||||
}
|
||||
|
||||
func (i *Uint64) Swap(v uint64) (old uint64) {
|
||||
old = atomic.SwapUint64(&i.v, v)
|
||||
return
|
||||
}
|
||||
33
util/atomicutil/uint64_test.go
Normal file
33
util/atomicutil/uint64_test.go
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2024 The CubeFS Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package atomicutil_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cubefs/cubefs/util/atomicutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestUint32(t *testing.T) {
|
||||
i := atomicutil.Uint32{}
|
||||
i.Store(1)
|
||||
require.EqualValues(t, 1, i.Load())
|
||||
require.EqualValues(t, 2, i.Add(1))
|
||||
require.EqualValues(t, 2, i.Swap(1))
|
||||
require.True(t, i.CompareAndSwap(1, 2))
|
||||
require.EqualValues(t, 2, i.Load())
|
||||
require.EqualValues(t, 1, i.Sub(1))
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user