102 lines
3.0 KiB
Go
102 lines
3.0 KiB
Go
package cachev2
|
|
|
|
import (
|
|
"context"
|
|
|
|
"fiskerinc.com/modules/common"
|
|
"fiskerinc.com/modules/logger"
|
|
redis "fiskerinc.com/modules/redisv2"
|
|
"github.com/pkg/errors"
|
|
|
|
"fiskerinc.com/modules/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
|
|
}
|