-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Implement relayminer query caching
- Loading branch information
Showing
15 changed files
with
404 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package cache | ||
|
||
import ( | ||
"sync" | ||
|
||
"github.com/pokt-network/poktroll/pkg/client/query" | ||
) | ||
|
||
var _ query.KeyValueCache[any] = (*keyValueCache[any])(nil) | ||
|
||
// keyValueCache is a simple in-memory key-value cache implementation. | ||
// It is safe for concurrent use. | ||
type keyValueCache[V any] struct { | ||
cacheMu sync.RWMutex | ||
valuesMap map[string]V | ||
} | ||
|
||
// NewKeyValueCache returns a new instance of a KeyValueCache. | ||
func NewKeyValueCache[T any]() query.KeyValueCache[T] { | ||
return &keyValueCache[T]{ | ||
valuesMap: make(map[string]T), | ||
} | ||
} | ||
|
||
// Get returns the value for the given key. | ||
// A boolean is returned as the second value to indicate if the key was found in the cache. | ||
func (c *keyValueCache[V]) Get(key string) (value V, found bool) { | ||
c.cacheMu.RLock() | ||
defer c.cacheMu.RUnlock() | ||
|
||
value, found = c.valuesMap[key] | ||
return value, found | ||
} | ||
|
||
// Set sets the value for the given key. | ||
// TODO_CONSIDERATION: Add a method to set many values and indicate whether it | ||
// is the result of a GetAll operation. This would allow us to know whether the | ||
// cache is populated with all the possible values, so any other GetAll operation | ||
// could be returned from the cache. | ||
func (c *keyValueCache[V]) Set(key string, value V) { | ||
c.cacheMu.Lock() | ||
defer c.cacheMu.Unlock() | ||
|
||
c.valuesMap[key] = value | ||
} | ||
|
||
// Delete deletes the value for the given key. | ||
func (c *keyValueCache[V]) Delete(key string) { | ||
c.cacheMu.Lock() | ||
defer c.cacheMu.Unlock() | ||
|
||
delete(c.valuesMap, key) | ||
} | ||
|
||
// Clear empties the whole cache. | ||
func (c *keyValueCache[V]) Clear() { | ||
c.cacheMu.Lock() | ||
defer c.cacheMu.Unlock() | ||
|
||
c.valuesMap = make(map[string]V) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package cache | ||
|
||
import ( | ||
"context" | ||
|
||
"cosmossdk.io/depinject" | ||
|
||
"github.com/pokt-network/poktroll/pkg/client" | ||
"github.com/pokt-network/poktroll/pkg/observable/channel" | ||
) | ||
|
||
// ClearableCache is an interface that defines the common methods for a cache object. | ||
type Cache interface { | ||
Clear() | ||
} | ||
|
||
// CacheOption is a function type for the option functions that can customize | ||
// the cache behavior. | ||
type CacheOption[C Cache] func(context.Context, depinject.Config, C) error | ||
|
||
// WithNewBlockCacheClearing is a cache option that clears the cache every time | ||
// a new block is observed. | ||
func WithNewBlockCacheClearing[C Cache](ctx context.Context, deps depinject.Config, cache C) error { | ||
var blockClient client.BlockClient | ||
if err := depinject.Inject(deps, &blockClient); err != nil { | ||
return err | ||
} | ||
|
||
channel.ForEach( | ||
ctx, | ||
blockClient.CommittedBlocksSequence(ctx), | ||
func(ctx context.Context, block client.Block) { | ||
cache.Clear() | ||
}, | ||
) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package cache | ||
|
||
import ( | ||
"sync" | ||
|
||
"github.com/pokt-network/poktroll/pkg/client/query" | ||
) | ||
|
||
var _ query.ParamsCache[any] = (*paramsCache[any])(nil) | ||
|
||
// paramsCache is a simple in-memory cache implementation for query parameters. | ||
// It does not involve key-value pairs, but only stores a single value. | ||
type paramsCache[T any] struct { | ||
cacheMu sync.RWMutex | ||
found bool | ||
value T | ||
} | ||
|
||
// NewParamsCache returns a new instance of a ParamsCache. | ||
func NewParamsCache[T any]() query.ParamsCache[T] { | ||
return ¶msCache[T]{} | ||
} | ||
|
||
// Get returns the value stored in the cache. | ||
// A boolean is returned as the second value to indicate if the value was found in the cache. | ||
func (c *paramsCache[T]) Get() (value T, found bool) { | ||
c.cacheMu.RLock() | ||
defer c.cacheMu.RUnlock() | ||
|
||
return c.value, c.found | ||
} | ||
|
||
// Set sets the value in the cache. | ||
func (c *paramsCache[T]) Set(value T) { | ||
c.cacheMu.Lock() | ||
defer c.cacheMu.Unlock() | ||
|
||
c.found = true | ||
c.value = value | ||
} | ||
|
||
// Clear empties the cache. | ||
func (c *paramsCache[T]) Clear() { | ||
c.cacheMu.Lock() | ||
defer c.cacheMu.Unlock() | ||
|
||
c.found = false | ||
c.value = zeroValue[T]() | ||
} | ||
|
||
// zeroValue is a generic helper which returns the zero value of the given type. | ||
func zeroValue[T any]() (zero T) { | ||
return zero | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package query | ||
|
||
// ParamsCache is an interface for a simple in-memory cache implementation for query parameters. | ||
type ParamsCache[T any] interface { | ||
Get() (T, bool) | ||
Set(T) | ||
Clear() | ||
} | ||
|
||
// KeyValueCache is an interface for a simple in-memory key-value cache implementation. | ||
type KeyValueCache[V any] interface { | ||
Get(string) (V, bool) | ||
Set(string, V) | ||
Delete(string) | ||
Clear() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.