Files
cloud-services/pkg/cachev2/vehicle_state_multi.go

102 lines
3.1 KiB
Go

package cachev2
import (
"context"
"github.com/fiskerinc/cloud-services/pkg/common"
"github.com/fiskerinc/cloud-services/pkg/logger"
redis "github.com/fiskerinc/cloud-services/pkg/redisv2"
"github.com/pkg/errors"
"github.com/fiskerinc/cloud-services/pkg/db/queries"
)
func GetVINListDigitalTwin(vins []string, redisClient *redis.Connection) (digitalTwins map[string]common.CarState, errorList []error) {
digitalTwins = make(map[string]common.CarState)
pipe := redisClient.TxPipeline()
responses := make([]QueryVehicleStatePreResponse, 0, len(vins))
for _, vin := range vins {
rr := QueryVehicleStatePreResponse{}
rr.CarSessionExists = pipe.SIsMember(context.Background(), redis.CarSessionsKey(), vin)
rr.HMISessionExists = pipe.SIsMember(context.Background(), redis.HMISessionsKey(), vin)
rr.CarState = pipe.HGetAll(context.Background(), redis.CarStateHashKey(vin))
responses = append(responses, rr)
}
_, err := pipe.Exec(context.Background())
if err != nil {
errorList = append(errorList, err)
return
}
for index, resStruct := range responses {
bb, err := resStruct.Resolve()
if err != nil {
err = errors.Wrapf(err, "VIN: %s", vins[index])
errorList = append(errorList, err)
continue
}
state, err := ParsePayloadForVehicleState(bb)
if err != nil {
err = errors.Wrapf(err, "VIN: %s", vins[index])
errorList = append(errorList, err)
}
if state != nil {
digitalTwins[vins[index]] = *state
}
}
return
}
type getALDigitalTwinDBFieldsResults struct {
results []common.CarPKCOSVersion
err error
}
func GetVINListALDigitalTwin(vins []string, redisClient *redis.Connection, carsDB queries.CarsInterface) (digitalTwinsAL map[string]common.CarStateAL, errorList []error) {
digitalTwinsAL = make(map[string]common.CarStateAL)
dbResultsChan := make(chan getALDigitalTwinDBFieldsResults)
// While the redis is fetching its stored info, we should go out to the database and fetch the database knowledge we need
// May want to put this information into a cache
go getALDigitalTwinDBFields(vins, carsDB, dbResultsChan)
digitalTwins, errorList := GetVINListDigitalTwin(vins, redisClient)
dbResults := <-dbResultsChan
if dbResults.err != nil {
errorList = append(errorList, dbResults.err)
return
}
for _, dbRes := range dbResults.results {
temp := common.CarStateAL{}
dt, ok := digitalTwins[dbRes.Vin]
if !ok {
logger.Warn().Str("VIN", dbRes.Vin).Msg("AL Digital Twin Missing Redis")
// Think I need to initiate it so we don't null memory maybe?
dt = common.CarState{}
}
temp.CarState = &dt
temp.OSVersion = dbRes.OSVersion
temp.PKCVersion = dbRes.PKCVersion
temp.SumsVersion = dbRes.SumsVersion
digitalTwinsAL[dbRes.Vin] = temp
}
return
}
// IDK how I feel about having this database functionality inside /cache
func getALDigitalTwinDBFields(vins []string, carsDB queries.CarsInterface, out chan getALDigitalTwinDBFieldsResults) {
results, err := carsDB.GetSoftwareAndPKCVersions(vins)
out <- getALDigitalTwinDBFieldsResults{
results: results,
err: err,
}
}
type ALDB interface {
GetCars() queries.CarsInterface
}