mirror of https://github.com/0xERR0R/blocky.git
WIP: quick&dirty list cache redis implementation
This commit is contained in:
parent
d64b399fdc
commit
a695d38c99
|
@ -1,11 +1,15 @@
|
|||
package stringcache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/0xERR0R/blocky/log"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"github.com/hako/durafmt"
|
||||
)
|
||||
|
||||
type StringCache interface {
|
||||
|
@ -18,6 +22,23 @@ type CacheFactory interface {
|
|||
Create() StringCache
|
||||
}
|
||||
|
||||
type redisStringCache struct {
|
||||
rdb *redis.Client
|
||||
key string
|
||||
}
|
||||
|
||||
func (cache *redisStringCache) ElementCount() int {
|
||||
return int(cache.rdb.SCard(context.Background(), cache.key).Val())
|
||||
}
|
||||
|
||||
func (cache *redisStringCache) Contains(searchString string) bool {
|
||||
now := time.Now()
|
||||
found := cache.rdb.SIsMember(context.Background(), cache.key, searchString).Val()
|
||||
log.Log().Infof("redis lookup in set '%s', domain '%s': result: %t, duration %s", cache.key, searchString, found, durafmt.Parse(time.Since(now)).String())
|
||||
|
||||
return found
|
||||
}
|
||||
|
||||
type stringCache map[int]string
|
||||
|
||||
func normalizeEntry(entry string) string {
|
||||
|
@ -54,6 +75,39 @@ func (cache stringCache) Contains(searchString string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
type redisStringCacheFactory struct {
|
||||
pipeline redis.Pipeliner
|
||||
name string
|
||||
rdb *redis.Client
|
||||
}
|
||||
|
||||
func newRedisStringCacheFactory(rdb *redis.Client, name string) CacheFactory {
|
||||
pipeline := rdb.Pipeline()
|
||||
pipeline.Del(context.Background(), name)
|
||||
|
||||
return &redisStringCacheFactory{
|
||||
rdb: rdb,
|
||||
pipeline: pipeline,
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *redisStringCacheFactory) AddEntry(entry string) {
|
||||
err := s.pipeline.SAdd(context.Background(), s.name, entry).Err()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *redisStringCacheFactory) Create() StringCache {
|
||||
// TODO batch
|
||||
s.pipeline.Exec(context.Background())
|
||||
return &redisStringCache{
|
||||
rdb: s.rdb,
|
||||
key: s.name,
|
||||
}
|
||||
}
|
||||
|
||||
type stringCacheFactory struct {
|
||||
// temporary map which holds sorted slice of strings grouped by string length
|
||||
tmp map[int][]string
|
||||
|
@ -194,9 +248,13 @@ func (r *chainedCacheFactory) Create() StringCache {
|
|||
}
|
||||
}
|
||||
|
||||
func NewChainedCacheFactory() CacheFactory {
|
||||
func NewChainedCacheFactory(name string) CacheFactory {
|
||||
return &chainedCacheFactory{
|
||||
stringCacheFactory: newStringCacheFactory(),
|
||||
regexCacheFactory: newRegexCacheFactory(),
|
||||
stringCacheFactory: newRedisStringCacheFactory(redis.NewClient(&redis.Options{
|
||||
Addr: "localhost:6379",
|
||||
Password: "", // no password set
|
||||
DB: 0, // use default DB
|
||||
}), name),
|
||||
regexCacheFactory: newRegexCacheFactory(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ var _ = Describe("Caches", func() {
|
|||
|
||||
Describe("Chained StringCache", func() {
|
||||
When("chained StringCache was created", func() {
|
||||
factory := NewChainedCacheFactory()
|
||||
factory := NewChainedCacheFactory("test")
|
||||
factory.AddEntry("/.*google.com/")
|
||||
factory.AddEntry("/^apple\\.(de|com)$/")
|
||||
factory.AddEntry("amazon.com")
|
||||
|
|
|
@ -146,11 +146,16 @@ func logger() *logrus.Entry {
|
|||
return log.PrefixedLog("list_cache")
|
||||
}
|
||||
|
||||
func (b *ListCache) cacheKey(groupName string) string {
|
||||
return fmt.Sprintf("cache_%s_%s", b.listType.String(), groupName)
|
||||
|
||||
}
|
||||
|
||||
// downloads and reads files with domain names and creates cache for them
|
||||
func (b *ListCache) createCacheForGroup(links []string) (stringcache.StringCache, error) {
|
||||
func (b *ListCache) createCacheForGroup(links []string, groupName string) (stringcache.StringCache, error) {
|
||||
var err error
|
||||
|
||||
factory := stringcache.NewChainedCacheFactory()
|
||||
factory := stringcache.NewChainedCacheFactory(b.cacheKey(groupName))
|
||||
|
||||
fileLinesChan := make(chan string, chanCap)
|
||||
errChan := make(chan error, chanCap)
|
||||
|
@ -226,7 +231,7 @@ func (b *ListCache) refresh(init bool) error {
|
|||
var err error
|
||||
|
||||
for group, links := range b.groupToLinks {
|
||||
cacheForGroup, e := b.createCacheForGroup(links)
|
||||
cacheForGroup, e := b.createCacheForGroup(links, group)
|
||||
if e != nil {
|
||||
err = multierror.Append(err, multierror.Prefix(e, fmt.Sprintf("can't create cache group '%s':", group)))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue