proxy_latency_cache.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package repository
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "github.com/Wei-Shaw/sub2api/internal/service"
  7. "github.com/redis/go-redis/v9"
  8. )
  9. const proxyLatencyKeyPrefix = "proxy:latency:"
  10. func proxyLatencyKey(proxyID int64) string {
  11. return fmt.Sprintf("%s%d", proxyLatencyKeyPrefix, proxyID)
  12. }
  13. type proxyLatencyCache struct {
  14. rdb *redis.Client
  15. }
  16. func NewProxyLatencyCache(rdb *redis.Client) service.ProxyLatencyCache {
  17. return &proxyLatencyCache{rdb: rdb}
  18. }
  19. func (c *proxyLatencyCache) GetProxyLatencies(ctx context.Context, proxyIDs []int64) (map[int64]*service.ProxyLatencyInfo, error) {
  20. results := make(map[int64]*service.ProxyLatencyInfo)
  21. if len(proxyIDs) == 0 {
  22. return results, nil
  23. }
  24. keys := make([]string, 0, len(proxyIDs))
  25. for _, id := range proxyIDs {
  26. keys = append(keys, proxyLatencyKey(id))
  27. }
  28. values, err := c.rdb.MGet(ctx, keys...).Result()
  29. if err != nil {
  30. return results, err
  31. }
  32. for i, raw := range values {
  33. if raw == nil {
  34. continue
  35. }
  36. var payload []byte
  37. switch v := raw.(type) {
  38. case string:
  39. payload = []byte(v)
  40. case []byte:
  41. payload = v
  42. default:
  43. continue
  44. }
  45. var info service.ProxyLatencyInfo
  46. if err := json.Unmarshal(payload, &info); err != nil {
  47. continue
  48. }
  49. results[proxyIDs[i]] = &info
  50. }
  51. return results, nil
  52. }
  53. func (c *proxyLatencyCache) SetProxyLatency(ctx context.Context, proxyID int64, info *service.ProxyLatencyInfo) error {
  54. if info == nil {
  55. return nil
  56. }
  57. payload, err := json.Marshal(info)
  58. if err != nil {
  59. return err
  60. }
  61. return c.rdb.Set(ctx, proxyLatencyKey(proxyID), payload, 0).Err()
  62. }