add backup filter
This commit is contained in:
		@ -7,6 +7,7 @@ import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/go-gost/core/metadata"
 | 
			
		||||
	mdutil "github.com/go-gost/core/metadata/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// default options for FailFilter
 | 
			
		||||
@ -131,8 +132,8 @@ type failFilter[T Selectable] struct {
 | 
			
		||||
	failTimeout time.Duration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FailFilter filters the dead node.
 | 
			
		||||
// A node is marked as dead if its failed count is greater than MaxFails.
 | 
			
		||||
// FailFilter filters the dead objects.
 | 
			
		||||
// An object is marked as dead if its failed count is greater than MaxFails.
 | 
			
		||||
func FailFilter[T Selectable](maxFails int, timeout time.Duration) Filter[T] {
 | 
			
		||||
	return &failFilter[T]{
 | 
			
		||||
		maxFails:    maxFails,
 | 
			
		||||
@ -140,7 +141,7 @@ func FailFilter[T Selectable](maxFails int, timeout time.Duration) Filter[T] {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Filter filters dead nodes.
 | 
			
		||||
// Filter filters dead objects.
 | 
			
		||||
func (f *failFilter[T]) Filter(vs ...T) []T {
 | 
			
		||||
	maxFails := f.maxFails
 | 
			
		||||
	failTimeout := f.failTimeout
 | 
			
		||||
@ -165,6 +166,35 @@ func (f *failFilter[T]) Filter(vs ...T) []T {
 | 
			
		||||
	return l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type backupFilter[T Selectable] struct{}
 | 
			
		||||
 | 
			
		||||
// BackupFilter filters the backup objects.
 | 
			
		||||
// An object is marked as backup if its metadata has backup flag.
 | 
			
		||||
func BackupFilter[T Selectable]() Filter[T] {
 | 
			
		||||
	return &backupFilter[T]{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Filter filters backup objects.
 | 
			
		||||
func (f *backupFilter[T]) Filter(vs ...T) []T {
 | 
			
		||||
	if len(vs) <= 1 {
 | 
			
		||||
		return vs
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var l, backups []T
 | 
			
		||||
	for _, v := range vs {
 | 
			
		||||
		if mdutil.GetBool(v.Metadata(), "backup") {
 | 
			
		||||
			backups = append(backups, v)
 | 
			
		||||
		} else {
 | 
			
		||||
			l = append(l, v)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(l) == 0 {
 | 
			
		||||
		return backups
 | 
			
		||||
	}
 | 
			
		||||
	return l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Marker interface {
 | 
			
		||||
	Time() time.Time
 | 
			
		||||
	Count() int64
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										139
									
								
								metadata/util/util.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								metadata/util/util.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,139 @@
 | 
			
		||||
package util
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/go-gost/core/metadata"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func GetBool(md metadata.Metadata, key string) (v bool) {
 | 
			
		||||
	if md == nil || !md.IsExists(key) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	switch vv := md.Get(key).(type) {
 | 
			
		||||
	case bool:
 | 
			
		||||
		return vv
 | 
			
		||||
	case int:
 | 
			
		||||
		return vv != 0
 | 
			
		||||
	case string:
 | 
			
		||||
		v, _ = strconv.ParseBool(vv)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetInt(md metadata.Metadata, key string) (v int) {
 | 
			
		||||
	if md == nil || !md.IsExists(key) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch vv := md.Get(key).(type) {
 | 
			
		||||
	case bool:
 | 
			
		||||
		if vv {
 | 
			
		||||
			v = 1
 | 
			
		||||
		}
 | 
			
		||||
	case int:
 | 
			
		||||
		return vv
 | 
			
		||||
	case string:
 | 
			
		||||
		v, _ = strconv.Atoi(vv)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetFloat(md metadata.Metadata, key string) (v float64) {
 | 
			
		||||
	if md == nil || !md.IsExists(key) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch vv := md.Get(key).(type) {
 | 
			
		||||
	case int:
 | 
			
		||||
		return float64(vv)
 | 
			
		||||
	case string:
 | 
			
		||||
		v, _ = strconv.ParseFloat(vv, 64)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetDuration(md metadata.Metadata, key string) (v time.Duration) {
 | 
			
		||||
	if md == nil || !md.IsExists(key) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch vv := md.Get(key).(type) {
 | 
			
		||||
	case int:
 | 
			
		||||
		return time.Duration(vv) * time.Second
 | 
			
		||||
	case string:
 | 
			
		||||
		v, _ = time.ParseDuration(vv)
 | 
			
		||||
		if v == 0 {
 | 
			
		||||
			n, _ := strconv.Atoi(vv)
 | 
			
		||||
			v = time.Duration(n) * time.Second
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetString(md metadata.Metadata, key string) (v string) {
 | 
			
		||||
	if md != nil {
 | 
			
		||||
		v, _ = md.Get(key).(string)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetStrings(md metadata.Metadata, key string) (ss []string) {
 | 
			
		||||
	if md == nil || !md.IsExists(key) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch v := md.Get(key).(type) {
 | 
			
		||||
	case []string:
 | 
			
		||||
		ss = v
 | 
			
		||||
	case []any:
 | 
			
		||||
		for _, vv := range v {
 | 
			
		||||
			if s, ok := vv.(string); ok {
 | 
			
		||||
				ss = append(ss, s)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetStringMap(md metadata.Metadata, key string) (m map[string]any) {
 | 
			
		||||
	if md == nil || !md.IsExists(key) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch vv := md.Get(key).(type) {
 | 
			
		||||
	case map[string]any:
 | 
			
		||||
		return vv
 | 
			
		||||
	case map[any]any:
 | 
			
		||||
		m = make(map[string]any)
 | 
			
		||||
		for k, v := range vv {
 | 
			
		||||
			m[fmt.Sprintf("%v", k)] = v
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetStringMapString(md metadata.Metadata, key string) (m map[string]string) {
 | 
			
		||||
	if md == nil || !md.IsExists(key) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch vv := md.Get(key).(type) {
 | 
			
		||||
	case map[string]any:
 | 
			
		||||
		m = make(map[string]string)
 | 
			
		||||
		for k, v := range vv {
 | 
			
		||||
			m[k] = fmt.Sprintf("%v", v)
 | 
			
		||||
		}
 | 
			
		||||
	case map[any]any:
 | 
			
		||||
		m = make(map[string]string)
 | 
			
		||||
		for k, v := range vv {
 | 
			
		||||
			m[fmt.Sprintf("%v", k)] = fmt.Sprintf("%v", v)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user