refactor
This commit is contained in:
106
rq/internal/update/serverchange.go
Normal file
106
rq/internal/update/serverchange.go
Normal file
@@ -0,0 +1,106 @@
|
||||
package update
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
|
||||
"zero/core/hash"
|
||||
"zero/core/jsonx"
|
||||
"zero/rq/internal"
|
||||
)
|
||||
|
||||
var ErrInvalidServerChange = errors.New("not a server change message")
|
||||
|
||||
type (
|
||||
weightedKey struct {
|
||||
Key string
|
||||
Weight int
|
||||
}
|
||||
|
||||
Snapshot struct {
|
||||
Keys []string
|
||||
WeightedKeys []weightedKey
|
||||
}
|
||||
|
||||
ServerChange struct {
|
||||
Previous Snapshot
|
||||
Current Snapshot
|
||||
Servers []string
|
||||
}
|
||||
)
|
||||
|
||||
func (s Snapshot) GetCode() string {
|
||||
keys := append([]string(nil), s.Keys...)
|
||||
sort.Strings(keys)
|
||||
weightedKeys := append([]weightedKey(nil), s.WeightedKeys...)
|
||||
sort.SliceStable(weightedKeys, func(i, j int) bool {
|
||||
return weightedKeys[i].Key < weightedKeys[j].Key
|
||||
})
|
||||
|
||||
digest := md5.New()
|
||||
for _, key := range keys {
|
||||
io.WriteString(digest, fmt.Sprintf("%s\n", key))
|
||||
}
|
||||
for _, wkey := range weightedKeys {
|
||||
io.WriteString(digest, fmt.Sprintf("%s:%d\n", wkey.Key, wkey.Weight))
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%x", digest.Sum(nil))
|
||||
}
|
||||
|
||||
func (sc ServerChange) CreateCurrentHash() *hash.ConsistentHash {
|
||||
curHash := hash.NewConsistentHash()
|
||||
|
||||
for _, key := range sc.Current.Keys {
|
||||
curHash.Add(key)
|
||||
}
|
||||
for _, wkey := range sc.Current.WeightedKeys {
|
||||
curHash.AddWithWeight(wkey.Key, wkey.Weight)
|
||||
}
|
||||
|
||||
return curHash
|
||||
}
|
||||
|
||||
func (sc ServerChange) CreatePrevHash() *hash.ConsistentHash {
|
||||
prevHash := hash.NewConsistentHash()
|
||||
|
||||
for _, key := range sc.Previous.Keys {
|
||||
prevHash.Add(key)
|
||||
}
|
||||
for _, wkey := range sc.Previous.WeightedKeys {
|
||||
prevHash.AddWithWeight(wkey.Key, wkey.Weight)
|
||||
}
|
||||
|
||||
return prevHash
|
||||
}
|
||||
|
||||
func (sc ServerChange) GetCode() string {
|
||||
return sc.Current.GetCode()
|
||||
}
|
||||
|
||||
func IsServerChange(message string) bool {
|
||||
return len(message) > 0 && message[0] == internal.ServerSensitivePrefix
|
||||
}
|
||||
|
||||
func (sc ServerChange) Marshal() (string, error) {
|
||||
body, err := jsonx.Marshal(sc)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(append([]byte{internal.ServerSensitivePrefix}, body...)), nil
|
||||
}
|
||||
|
||||
func UnmarshalServerChange(body string) (ServerChange, error) {
|
||||
if len(body) == 0 {
|
||||
return ServerChange{}, ErrInvalidServerChange
|
||||
}
|
||||
|
||||
var change ServerChange
|
||||
err := jsonx.UnmarshalFromString(body[1:], &change)
|
||||
|
||||
return change, err
|
||||
}
|
||||
Reference in New Issue
Block a user