// Package diagram provide diagram data structure and operation package diagram import ( "context" "fmt" "strconv" "github.com/redis/go-redis/v9" ) // RedisClient define struct to accessing redis data that does not require the use of distributed locks type RedisClient struct { Client *redis.Client } // QueryLatestMeasurementValue returns the score whose member contains the // greatest numeric timestamp. Measurement ZSets currently store timestamp in // member and measurement value in score. func (rc *RedisClient) QueryLatestMeasurementValue(ctx context.Context, key string) (float64, error) { if rc.Client == nil { return 0, fmt.Errorf("redis client is not initialized") } members, err := rc.Client.ZRangeWithScores(ctx, key, 0, -1).Result() if err != nil { return 0, err } return latestMeasurementValue(members, key) } func latestMeasurementValue(members []redis.Z, key string) (float64, error) { if len(members) == 0 { return 0, fmt.Errorf("real-time measurement value not found for key %q", key) } var latestTimestamp int64 var latestValue float64 found := false for _, member := range members { timestamp, err := strconv.ParseInt(fmt.Sprint(member.Member), 10, 64) if err != nil { continue } if !found || timestamp > latestTimestamp { latestTimestamp = timestamp latestValue = member.Score found = true } } if !found { return 0, fmt.Errorf("real-time measurement timestamps are invalid for key %q", key) } return latestValue, nil } // NewRedisClient define func of new redis client instance func NewRedisClient() *RedisClient { return &RedisClient{ Client: GetRedisClientInstance(), } } // QueryByZRange define func to query real time data from redis zset func (rc *RedisClient) QueryByZRange(ctx context.Context, key string, size int64) ([]redis.Z, error) { client := rc.Client args := redis.ZRangeArgs{ Key: key, Start: 0, Stop: size, ByScore: false, ByLex: false, Rev: false, Offset: 0, Count: 0, } return client.ZRangeArgsWithScores(ctx, args).Result() }