Initial cloud-services repo - gateway service + pkg modules
This commit is contained in:
141
pkg/cache/drivers.go
vendored
Normal file
141
pkg/cache/drivers.go
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"fiskerinc.com/modules/common"
|
||||
"fiskerinc.com/modules/db/queries"
|
||||
"fiskerinc.com/modules/logger"
|
||||
"fiskerinc.com/modules/redis"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func NewDriversCache(redisClient redis.ClientPoolInterface, cars queries.CarsInterface) *DriversCache {
|
||||
return &DriversCache{
|
||||
redisClientPool: redisClient,
|
||||
cars: cars,
|
||||
}
|
||||
}
|
||||
|
||||
type DriversCache struct {
|
||||
redisClientPool redis.ClientPoolInterface
|
||||
cars queries.CarsInterface
|
||||
}
|
||||
|
||||
func (dc *DriversCache) RedisClientPool() redis.ClientPoolInterface {
|
||||
return dc.redisClientPool
|
||||
}
|
||||
|
||||
func (dc *DriversCache) Cars() queries.CarsInterface {
|
||||
return dc.cars
|
||||
}
|
||||
|
||||
func (dc *DriversCache) hasCachedNoDrivers(drivers []string) bool {
|
||||
// Redis will return []string{""} for no drivers
|
||||
return len(drivers) == 1 && len(drivers[0]) == 0
|
||||
}
|
||||
|
||||
func (dc *DriversCache) cacheDrivers(key string, drivers []string) error {
|
||||
client := dc.redisClientPool.GetFromPool()
|
||||
defer client.Close()
|
||||
// cache driver IDs
|
||||
if len(drivers) > 0 {
|
||||
return client.NewSet(key, drivers, redisObjectExpire)
|
||||
}
|
||||
|
||||
// Redis will not take an empty array as an arg
|
||||
return client.NewSet(key, nil, redisObjectExpire)
|
||||
}
|
||||
|
||||
// RetrieveDriverIDs retrieves IDs from redis or from DB and proceeds to cache both the drivers and IDs
|
||||
// redis keys:
|
||||
//
|
||||
// car:<VIN>:drivers
|
||||
func (dc *DriversCache) RetrieveDriverIDs(vin string) ([]string, error) {
|
||||
var driverIDs []string
|
||||
driverIDsKey := redis.CarToAllDriversKey(vin)
|
||||
|
||||
// retrieve IDs from redis
|
||||
client := dc.redisClientPool.GetFromPool()
|
||||
err := client.GetSet(driverIDsKey, &driverIDs)
|
||||
if err != nil {
|
||||
logger.Warn().Err(err).Send()
|
||||
}
|
||||
client.Close()
|
||||
|
||||
if dc.hasCachedNoDrivers(driverIDs) {
|
||||
return []string{}, nil
|
||||
}
|
||||
if len(driverIDs) > 0 {
|
||||
return driverIDs, nil
|
||||
}
|
||||
|
||||
// if IDs not present in redis perform DB lookup
|
||||
var drivers []common.CarToDriver
|
||||
drivers, err = dc.cars.GetDrivers(vin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, driver := range drivers {
|
||||
driverIDs = append(driverIDs, driver.DriverID)
|
||||
}
|
||||
|
||||
err = dc.cacheDrivers(driverIDsKey, driverIDs)
|
||||
if err != nil {
|
||||
return driverIDs, err
|
||||
}
|
||||
|
||||
return driverIDs, nil
|
||||
}
|
||||
|
||||
// RetrieveDriverIDsAsSet retrieves IDs from redis or from DB and proceeds to cache both the drivers and IDs
|
||||
// redis keys:
|
||||
//
|
||||
// car:<VIN>:drivers
|
||||
func (dc *DriversCache) RetrieveDriverIDsAsSet(vin string) (map[string]struct{}, error) {
|
||||
driverIDs, err := dc.RetrieveDriverIDs(vin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var dIDsSet = make(map[string]struct{})
|
||||
for _, did := range driverIDs {
|
||||
dIDsSet[did] = struct{}{}
|
||||
}
|
||||
|
||||
return dIDsSet, nil
|
||||
}
|
||||
|
||||
func (dc *DriversCache) IsDriverOfVIN(vin string, driverid string) (bool, error) {
|
||||
ids, err := dc.RetrieveDriverIDs(vin)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, id := range ids {
|
||||
if id == driverid {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, dc.NotDriverError(vin, driverid)
|
||||
}
|
||||
|
||||
// Add driver to database and cache
|
||||
func (dc *DriversCache) AddDriver(car *common.Car, driver *common.Driver, role string) (*common.CarToDriver, error) {
|
||||
|
||||
relation, err := dc.cars.AddDriver(car, driver, role)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
driverIDsKey := redis.CarToAllDriversKey(car.VIN)
|
||||
|
||||
client := dc.redisClientPool.GetFromPool()
|
||||
defer client.Close()
|
||||
client.AddToSet(driverIDsKey, driver.ID, redisObjectExpire)
|
||||
return relation, nil
|
||||
}
|
||||
|
||||
func (dc DriversCache) NotDriverError(vin string, driverid string) error {
|
||||
return errors.Errorf("id %s is not a driver for vin %v", driverid, vin)
|
||||
}
|
||||
Reference in New Issue
Block a user