Initial cloud-services repo - gateway service + pkg modules
This commit is contained in:
124
pkg/cache/vehicles.go
vendored
Normal file
124
pkg/cache/vehicles.go
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fiskerinc.com/modules/common"
|
||||
orm "fiskerinc.com/modules/db/queries"
|
||||
"fmt"
|
||||
"github.com/ReneKroon/ttlcache/v2"
|
||||
"github.com/pkg/errors"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrCacheNotInitialized = errors.New("cache is not initialized")
|
||||
)
|
||||
|
||||
type VehicleCacher interface {
|
||||
Set(key VehiclesTTLParams, value *VehiclesTTLResult) error
|
||||
Get(key VehiclesTTLParams) (*VehiclesTTLResult, error)
|
||||
}
|
||||
|
||||
type VehiclesCache struct {
|
||||
duration time.Duration
|
||||
limit int
|
||||
cache *ttlcache.Cache
|
||||
onceCache *sync.Once
|
||||
}
|
||||
|
||||
func (c *VehiclesCache) Duration() time.Duration {
|
||||
return c.duration
|
||||
}
|
||||
|
||||
func (c *VehiclesCache) Limit() int {
|
||||
return c.limit
|
||||
}
|
||||
|
||||
func (c *VehiclesCache) Once() *sync.Once {
|
||||
return c.onceCache
|
||||
}
|
||||
|
||||
func (c *VehiclesCache) SetCache(cache *ttlcache.Cache) {
|
||||
c.cache = cache
|
||||
}
|
||||
|
||||
func (c *VehiclesCache) Cache() *ttlcache.Cache {
|
||||
return c.cache
|
||||
}
|
||||
|
||||
type VehiclesTTLParams struct {
|
||||
Options orm.PageQueryOptions `json:"options"`
|
||||
CarOnlineFilter *common.CarOnlineFilter `json:"car_online_filter"`
|
||||
Search string `json:"search"`
|
||||
}
|
||||
|
||||
type VehiclesTTLResult struct {
|
||||
Data []common.Car `json:"data"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
func NewVehiclesCache(duration time.Duration, limit int) (*VehiclesCache, error) {
|
||||
c := &VehiclesCache{
|
||||
duration: duration,
|
||||
limit: limit,
|
||||
onceCache: &sync.Once{},
|
||||
}
|
||||
|
||||
if cache := logCache(c); cache == nil {
|
||||
return nil, ErrCacheNotInitialized
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
func (c *VehiclesCache) Set(key VehiclesTTLParams, value *VehiclesTTLResult) error {
|
||||
if cache := logCache(c); cache == nil {
|
||||
return ErrCacheNotInitialized
|
||||
}
|
||||
|
||||
keyBts, err := json.Marshal(key)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "failed to marshal key")
|
||||
}
|
||||
|
||||
return c.cache.Set(string(keyBts), value)
|
||||
}
|
||||
|
||||
func (c *VehiclesCache) Get(key VehiclesTTLParams) (*VehiclesTTLResult, error) {
|
||||
if cache := logCache(c); cache == nil {
|
||||
return nil, ErrCacheNotInitialized
|
||||
}
|
||||
|
||||
keyBts, err := json.Marshal(key)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "failed to marshal key")
|
||||
}
|
||||
|
||||
value, err := c.cache.Get(string(keyBts))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get value from cache: %w", err)
|
||||
}
|
||||
|
||||
return value.(*VehiclesTTLResult), nil
|
||||
}
|
||||
|
||||
type Cacher interface {
|
||||
Duration() time.Duration
|
||||
Limit() int
|
||||
Once() *sync.Once
|
||||
Cache() *ttlcache.Cache
|
||||
SetCache(*ttlcache.Cache)
|
||||
}
|
||||
|
||||
func logCache(cacher Cacher) *ttlcache.Cache {
|
||||
cacher.Once().Do(func() {
|
||||
if cacher.Cache() == nil {
|
||||
cache := ttlcache.NewCache()
|
||||
cache.SetTTL(cacher.Duration())
|
||||
cache.SetCacheSizeLimit(cacher.Limit())
|
||||
cacher.SetCache(cache)
|
||||
}
|
||||
})
|
||||
|
||||
return cacher.Cache()
|
||||
}
|
||||
Reference in New Issue
Block a user