56 lines
1.2 KiB
Go
56 lines
1.2 KiB
Go
package snowflake
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
"time"
|
|
|
|
"sandc/pkg/utils/janitor"
|
|
|
|
log2 "github.com/go-kratos/kratos/v2/log"
|
|
|
|
"github.com/go-redis/redis/v8"
|
|
)
|
|
|
|
var (
|
|
SNOWFLAKE_KEY = "snowflake:"
|
|
SNOWFLAKE_NODE_TTL = 60
|
|
EMPTY_NODE_ERROR = errors.New("nodemax is full")
|
|
)
|
|
|
|
func GetSnowflakeNode(red redis.Cmdable) *Node {
|
|
hostname, _ := os.Hostname()
|
|
var key string
|
|
var nodeID int
|
|
var value string
|
|
for i := 0; i < 1023; i++ {
|
|
nodeID = i
|
|
field := strconv.Itoa(i)
|
|
value = fmt.Sprintf("%s#%d", hostname, os.Getpid())
|
|
key = SNOWFLAKE_KEY + field
|
|
cmd := red.SetNX(context.Background(), key, value, time.Duration(SNOWFLAKE_NODE_TTL)*time.Second)
|
|
if cmd.Val() {
|
|
log2.Infof("GetSnowflakeNode: key[%s] value[%s]", key, value)
|
|
break
|
|
} else {
|
|
log2.Errorf("GetSnowflakeNode: key[%s] value[%s] err[%v]", key, value, cmd.Err())
|
|
}
|
|
}
|
|
if key == "" {
|
|
log.Fatalln(EMPTY_NODE_ERROR)
|
|
}
|
|
sf, err := NewNode(int64(nodeID))
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
j := janitor.NewJanitor(context.Background(), time.Second*3)
|
|
j.Run(func() {
|
|
red.Expire(context.Background(), key, time.Duration(SNOWFLAKE_NODE_TTL)*time.Second)
|
|
})
|
|
return sf
|
|
}
|