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 }