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 }