79 lines
2.0 KiB
Go
79 lines
2.0 KiB
Go
// 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()
|
|
}
|