MM-59932: Migrate remaining caches to Redis (#27880)

- We introduce 2 new APIs:
1. Scan: this allows incremental iteration
without blocking the Redis server and is the
recommended way to iterate over keys. With this,
we have entirely removed the need for Keys.
2. RemoveMulti: this allows deletion of multiple
keys in a single operation which optimizes
network round trips.

- While here, we make a small improvement to
GetStatusFromCache, where we remove the shallow
copy which wasn't necessary because we always
serialize the data from the cache.
- We do not use Redis for session cache because of
frequent requests to iterate the entire cache which leads
to a lot of `SCAN` calls.
- Avoid broadcasting status update messages for Redis case.
- Setting cache expiry for status cache
- Removing .Set method altogether to prevent
any chances of setting an item with no expiry.

https://mattermost.atlassian.net/browse/MM-59932

```release-note
NONE
```
Этот коммит содержится в:
Agniva De Sarker
2024-08-13 14:18:25 +05:30
коммит произвёл GitHub
родитель e5842e67a8
Коммит a1012d33eb
19 изменённых файлов: 437 добавлений и 212 удалений

30
server/platform/services/cache/lru_striped.go поставляемый
Просмотреть файл

@@ -4,6 +4,7 @@
package cache
import (
"errors"
"fmt"
"math"
"time"
@@ -62,11 +63,6 @@ func (L LRUStriped) Purge() error {
return nil
}
// Set does the same as LRU.Set
func (L LRUStriped) Set(key string, value any) error {
return L.keyBucket(key).Set(key, value)
}
// SetWithDefaultExpiry does the same as LRU.SetWithDefaultExpiry
func (L LRUStriped) SetWithDefaultExpiry(key string, value any) error {
return L.keyBucket(key).SetWithDefaultExpiry(key, value)
@@ -95,16 +91,22 @@ func (L LRUStriped) Remove(key string) error {
return L.keyBucket(key).Remove(key)
}
// Keys does the same as LRU.Keys. However, because this is lock-free, keys might be
// inserted or removed from a previously scanned LRU cache.
// This is not as precise as using a single LRU instance.
func (L LRUStriped) Keys() ([]string, error) {
var keys []string
for _, lru := range L.buckets {
k, _ := lru.Keys() // Keys never returns any error
keys = append(keys, k...)
// RemoveMulti does the same as LRU.RemoveMulti
func (L LRUStriped) RemoveMulti(keys []string) error {
var err error
for _, key := range keys {
err = errors.Join(err, L.keyBucket(key).Remove(key))
}
return keys, nil
return err
}
// Scan is basically a copy of Keys in LRU mode.
// See comment in LRU.Scan.
func (L LRUStriped) Scan(f func([]string) error) error {
for _, lru := range L.buckets {
lru.Scan(f)
}
return nil
}
// Len does the same as LRU.Len. As for LRUStriped.Keys, this call cannot be precise.