mirror of
https://github.com/cubefs/cubefs.git
synced 2026-08-02 02:00:56 +00:00
style(common): using generic version of functions
. #1000657118 Signed-off-by: slasher <shenjie1@oppo.com>
This commit is contained in:
parent
a07809fc95
commit
dec013044a
@ -95,7 +95,7 @@ func showClusters(c *grumble.Context) error {
|
||||
fmt.Println()
|
||||
}
|
||||
fmt.Printf("\tspace in region: %s (%s / %s)\n", region,
|
||||
common.ColorizeInt64(-available, capacity).Sprint(humanize.IBytes(uint64(available))),
|
||||
common.ColorizeInteger(-available, capacity).Sprint(humanize.IBytes(uint64(available))),
|
||||
humanize.IBytes(uint64(capacity)))
|
||||
}
|
||||
|
||||
@ -126,7 +126,7 @@ func showClusterWithConfig() error {
|
||||
fmt.Println()
|
||||
|
||||
fmt.Printf("\tspace in cluster: %s (%s / %s)\n", clusterID,
|
||||
common.ColorizeInt64(-stat.BlobNodeSpaceStat.WritableSpace, stat.BlobNodeSpaceStat.TotalSpace).
|
||||
common.ColorizeInteger(-stat.BlobNodeSpaceStat.WritableSpace, stat.BlobNodeSpaceStat.TotalSpace).
|
||||
Sprint(humanize.IBytes(uint64(stat.BlobNodeSpaceStat.WritableSpace))),
|
||||
humanize.IBytes(uint64(stat.BlobNodeSpaceStat.TotalSpace)))
|
||||
}
|
||||
|
||||
@ -207,33 +207,26 @@ func cmdListVolumeUnits(c *grumble.Context) error {
|
||||
n := len(volumeInfo.Units)
|
||||
loader := common.Loader(n)
|
||||
|
||||
taskArgs := make([]any, n)
|
||||
for i, arg := range volumeInfo.Units {
|
||||
taskArgs[i] = arg
|
||||
}
|
||||
chunkInfos := make([]string, n)
|
||||
task.C(func(i int, taskArgs any) {
|
||||
unit := taskArgs.(clustermgr.Unit)
|
||||
chunkInfos := task.ConcurrentResult(func(_ int, unit clustermgr.Unit) string {
|
||||
disk, err := cmClient.DiskInfo(ctx, unit.DiskID)
|
||||
if err != nil {
|
||||
chunkInfos[i] = fmt.Sprintf("ERROR: get disk %d %s", unit.DiskID, err.Error())
|
||||
loader <- 1
|
||||
return
|
||||
return fmt.Sprintf("ERROR: get disk %d %s", unit.DiskID, err.Error())
|
||||
}
|
||||
info, err := blobnodeCli.StatChunk(ctx, disk.Host,
|
||||
&blobnode.StatChunkArgs{
|
||||
DiskID: unit.DiskID,
|
||||
Vuid: unit.Vuid,
|
||||
})
|
||||
if err != nil {
|
||||
chunkInfos[i] = fmt.Sprintf("ERROR: %s %d %s", disk.Host, unit.Vuid, err.Error())
|
||||
} else if verbose {
|
||||
chunkInfos[i] = cfmt.ChunkInfoJoin(info, "\t")
|
||||
} else {
|
||||
chunkInfos[i] = fmt.Sprint(info)
|
||||
}
|
||||
|
||||
loader <- 1
|
||||
}, taskArgs)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("ERROR: %s %d %s", disk.Host, unit.Vuid, err.Error())
|
||||
} else if verbose {
|
||||
return cfmt.ChunkInfoJoin(info, "\t")
|
||||
}
|
||||
return fmt.Sprint(info)
|
||||
}, volumeInfo.Units...)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
fmt.Println("chunks:")
|
||||
|
||||
@ -33,8 +33,8 @@ func VolumeInfoF(vol *clustermgr.VolumeInfo) []string {
|
||||
if vol == nil {
|
||||
return nilStrings[:]
|
||||
}
|
||||
usedC := common.ColorizeUint64(vol.Used, vol.Total)
|
||||
freeC := common.ColorizeUint64Free(vol.Free, vol.Total)
|
||||
usedC := common.ColorizeInteger(vol.Used, vol.Total)
|
||||
freeC := common.ColorizeIntegerFree(vol.Free, vol.Total)
|
||||
vals := make([]string, 0, 32)
|
||||
vals = append(vals, []string{
|
||||
fmt.Sprintf("Vid : %d", vol.Vid),
|
||||
@ -92,7 +92,7 @@ func ClusterInfoF(info *clustermgr.ClusterInfo) []string {
|
||||
if info == nil {
|
||||
return nilStrings[:]
|
||||
}
|
||||
avaiC := common.ColorizeInt64(-info.Available, info.Capacity)
|
||||
avaiC := common.ColorizeInteger(-info.Available, info.Capacity)
|
||||
vals := make([]string, 0, 8)
|
||||
vals = append(vals, []string{
|
||||
fmt.Sprintf("Region : %s", info.Region),
|
||||
|
||||
@ -16,6 +16,8 @@ package common
|
||||
|
||||
import (
|
||||
"github.com/fatih/color"
|
||||
|
||||
"github.com/cubefs/cubefs/blobstore/util"
|
||||
)
|
||||
|
||||
// colorize defined
|
||||
@ -97,7 +99,7 @@ func Colorize(percent int) *color.Color {
|
||||
}
|
||||
|
||||
// ColorizeFloat color by float64 [-1.0, 1.0] ratio
|
||||
func ColorizeFloat(ratio float64) *color.Color {
|
||||
func ColorizeFloat[T util.Float](ratio T) *color.Color {
|
||||
return Colorize(int(ratio * 100))
|
||||
}
|
||||
|
||||
@ -108,37 +110,13 @@ func percentIfFree(free bool, percent int) int {
|
||||
return percent
|
||||
}
|
||||
|
||||
// ColorizeInt by int
|
||||
func ColorizeInt(used, total int) *color.Color {
|
||||
return Colorize(percentIfFree(used < 0, used*100/total))
|
||||
}
|
||||
|
||||
// ColorizeInt32 by int32
|
||||
func ColorizeInt32(used, total int32) *color.Color {
|
||||
// ColorizeInteger colorize by any integer type
|
||||
// When used < 0 (signed types only), it indicates free space calculation
|
||||
func ColorizeInteger[T util.Integer](used, total T) *color.Color {
|
||||
return Colorize(percentIfFree(used < 0, int(used*100/total)))
|
||||
}
|
||||
|
||||
// ColorizeInt64 by int64
|
||||
func ColorizeInt64(used, total int64) *color.Color {
|
||||
return Colorize(percentIfFree(used < 0, int(used*100/total)))
|
||||
}
|
||||
|
||||
// ColorizeUint32 by uint32
|
||||
func ColorizeUint32(used, total uint32) *color.Color {
|
||||
return Colorize(int(used * 100 / total))
|
||||
}
|
||||
|
||||
// ColorizeUint64 by uint64
|
||||
func ColorizeUint64(used, total uint64) *color.Color {
|
||||
return Colorize(int(used * 100 / total))
|
||||
}
|
||||
|
||||
// ColorizeUint32Free free by uint32
|
||||
func ColorizeUint32Free(free, total uint32) *color.Color {
|
||||
return Colorize(percentIfFree(true, -int(free*100/total)))
|
||||
}
|
||||
|
||||
// ColorizeUint64Free free by uint64
|
||||
func ColorizeUint64Free(free, total uint64) *color.Color {
|
||||
// ColorizeIntegerFree colorize free space by any integer type
|
||||
func ColorizeIntegerFree[T util.Integer](free, total T) *color.Color {
|
||||
return Colorize(percentIfFree(true, -int(free*100/total)))
|
||||
}
|
||||
|
||||
@ -17,7 +17,6 @@ package common_test
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cubefs/cubefs/blobstore/cli/common"
|
||||
"github.com/cubefs/cubefs/blobstore/cli/common/fmt"
|
||||
@ -59,7 +58,6 @@ func TestCmdCommonColorRatio(t *testing.T) {
|
||||
{1000, 100, "highlight [Dead]"},
|
||||
}
|
||||
|
||||
rand.Seed(time.Now().Unix())
|
||||
for _, cs := range cases {
|
||||
for i := 0; i < 10; i++ {
|
||||
percent := rand.Intn(cs.rand) + cs.offset
|
||||
@ -78,24 +76,19 @@ func TestCmdCommonColorRatio(t *testing.T) {
|
||||
f := rand.Float64()
|
||||
c := common.ColorizeFloat(f)
|
||||
c.Printf("used(%.3f) unknow ", f)
|
||||
c = common.ColorizeFloat(-f)
|
||||
c = common.ColorizeFloat(-float32(f))
|
||||
c.Printf("free(%.3f) unknow ", -f)
|
||||
fmt.Println()
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
common.ColorizeInt(0, 100).Printf("ColorizeInt --> used(%d/%d) white\n", 0, 100)
|
||||
common.ColorizeInt(-1, 1000).Printf("ColorizeInt --> free(%d/%d) dead", -1, 10000)
|
||||
common.ColorizeInteger(0, 100).Printf("Int --> used(%d/%d) white\n", 0, 100)
|
||||
common.ColorizeInteger(-1, 1000).Printf("Int --> free(%d/%d) dead", -1, 10000)
|
||||
fmt.Println()
|
||||
|
||||
common.ColorizeInt(80, 100).Printf("ColorizeInt --> used(%d/%d) yellow\n", 80, 100)
|
||||
common.ColorizeInt(-80, 100).Printf("ColorizeInt --> free(%d/%d) green\n", 80, 100)
|
||||
common.ColorizeInt32(80, 100).Printf("ColorizeInt32 --> used(%d/%d) yellow\n", 80, 100)
|
||||
common.ColorizeInt32(-80, 100).Printf("ColorizeInt32 --> free(%d/%d) green\n", 80, 100)
|
||||
common.ColorizeInt64(80, 100).Printf("ColorizeInt64 --> used(%d/%d) yellow\n", 80, 100)
|
||||
common.ColorizeInt64(-80, 100).Printf("ColorizeInt64 --> free(%d/%d) green\n", 80, 100)
|
||||
common.ColorizeUint32(80, 100).Printf("ColorizeUint32 --> used(%d/%d) yellow\n", 80, 100)
|
||||
common.ColorizeUint32Free(80, 100).Printf("ColorizeUint32Free --> free(%d/%d) green\n", 80, 100)
|
||||
common.ColorizeUint64(80, 100).Printf("ColorizeUint64 --> used(%d/%d) yellow\n", 80, 100)
|
||||
common.ColorizeUint64Free(80, 100).Printf("ColorizeUint64Free --> free(%d/%d) green\n", 80, 100)
|
||||
common.ColorizeInteger(80, 100).Printf("Int --> used(%d/%d) yellow\n", 80, 100)
|
||||
common.ColorizeInteger(-80, 100).Printf("Int --> free(%d/%d) green\n", 80, 100)
|
||||
common.ColorizeInteger(int32(80), 100).Printf("Int32 --> used(%d/%d) yellow\n", 80, 100)
|
||||
common.ColorizeInteger(-80, int32(100)).Printf("Int32 --> free(%d/%d) green\n", 80, 100)
|
||||
common.ColorizeIntegerFree(uint64(80), 100).Printf("Uint64 --> free(%d/%d) green\n", 80, 100)
|
||||
}
|
||||
|
||||
@ -16,23 +16,15 @@ package task
|
||||
|
||||
import "context"
|
||||
|
||||
var (
|
||||
// C alias of Concurrent
|
||||
C = Concurrent
|
||||
// CC alias of ConcurrentContext
|
||||
CC = ConcurrentContext
|
||||
)
|
||||
|
||||
// Concurrent is tasks run concurrently.
|
||||
func Concurrent(f func(index int, arg interface{}), args []interface{}) {
|
||||
ConcurrentContext(context.Background(), f, args)
|
||||
func Concurrent[T any](f func(index int, arg T), args ...T) {
|
||||
ConcurrentContext(context.Background(), f, args...)
|
||||
}
|
||||
|
||||
// ConcurrentContext is tasks run concurrently with context.
|
||||
// How to make []interface{} see: https://golang.org/doc/faq#convert_slice_of_interface
|
||||
func ConcurrentContext(ctx context.Context, f func(index int, arg interface{}), args []interface{}) {
|
||||
func ConcurrentContext[T any](ctx context.Context, f func(index int, arg T), args ...T) {
|
||||
tasks := make([]func() error, len(args))
|
||||
for ii := 0; ii < len(args); ii++ {
|
||||
for ii := range args {
|
||||
index, arg := ii, args[ii]
|
||||
tasks[ii] = func() error {
|
||||
f(index, arg)
|
||||
@ -41,3 +33,23 @@ func ConcurrentContext(ctx context.Context, f func(index int, arg interface{}),
|
||||
}
|
||||
Run(ctx, tasks...)
|
||||
}
|
||||
|
||||
// ConcurrentResult runs tasks concurrently and collects results.
|
||||
func ConcurrentResult[T, R any](f func(index int, arg T) R, args ...T) []R {
|
||||
return ConcurrentResultContext(context.Background(), f, args...)
|
||||
}
|
||||
|
||||
// ConcurrentResultContext runs tasks concurrently with context and collects results.
|
||||
func ConcurrentResultContext[T, R any](ctx context.Context, f func(index int, arg T) R, args ...T) []R {
|
||||
results := make([]R, len(args))
|
||||
tasks := make([]func() error, len(args))
|
||||
for ii := range args {
|
||||
idx, arg := ii, args[ii]
|
||||
tasks[ii] = func() error {
|
||||
results[idx] = f(idx, arg)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
Run(ctx, tasks...)
|
||||
return results
|
||||
}
|
||||
|
||||
@ -28,11 +28,18 @@ import (
|
||||
|
||||
func TestTaskExecuteConcurrent(t *testing.T) {
|
||||
unique := uint32(0)
|
||||
args := []interface{}{uint32(1), uint32(2), uint32(4)}
|
||||
task.C(func(index int, arg interface{}) {
|
||||
task.Concurrent(func(index int, arg uint32) {
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
atomic.AddUint32(&unique, arg.(uint32))
|
||||
}, args)
|
||||
atomic.AddUint32(&unique, arg)
|
||||
}, 1, 2, 4) // copy mode, call Concurrent will create args = []uint32{1, 2, 4}
|
||||
require.Equal(t, uint32(7), atomic.LoadUint32(&unique))
|
||||
|
||||
atomic.StoreUint32(&unique, 0)
|
||||
args := []uint32{1, 2, 4}
|
||||
task.Concurrent(func(index int, arg uint32) {
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
atomic.AddUint32(&unique, arg)
|
||||
}, args...) // reference mode
|
||||
require.Equal(t, uint32(7), atomic.LoadUint32(&unique))
|
||||
}
|
||||
|
||||
@ -40,10 +47,10 @@ func TestTaskExecuteContextCancel(t *testing.T) {
|
||||
unique := uint32(0)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
err := task.Run(ctx, func() error {
|
||||
task.C(func(index int, arg interface{}) {
|
||||
task.Concurrent(func(index int, arg uint32) {
|
||||
time.Sleep(time.Millisecond * 2000)
|
||||
atomic.AddUint32(&unique, 1)
|
||||
}, []interface{}{1, 2, 4})
|
||||
}, 1, 2, 4)
|
||||
return nil
|
||||
}, func() error {
|
||||
time.Sleep(time.Millisecond * 5000)
|
||||
@ -55,3 +62,18 @@ func TestTaskExecuteContextCancel(t *testing.T) {
|
||||
require.Contains(t, err.Error(), "canceled")
|
||||
require.Equal(t, uint32(0), atomic.LoadUint32(&unique))
|
||||
}
|
||||
|
||||
func TestTaskExecuteConcurrentResult(t *testing.T) {
|
||||
{
|
||||
results := task.ConcurrentResult(func(index int, arg string) int {
|
||||
return len(arg)
|
||||
})
|
||||
require.Empty(t, len(results))
|
||||
}
|
||||
{
|
||||
results := task.ConcurrentResult(func(index int, arg int) int {
|
||||
return arg * arg
|
||||
}, 1, 2, 4, 7)
|
||||
require.Equal(t, []int{1, 4, 16, 49}, results)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user