Initial cloud-services repo - gateway service + pkg modules
This commit is contained in:
93
pkg/towmanparklocation/parklocation.go
Normal file
93
pkg/towmanparklocation/parklocation.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package towmanparklocation
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"fiskerinc.com/modules/cachev2"
|
||||
"fiskerinc.com/modules/db"
|
||||
"fiskerinc.com/modules/logger"
|
||||
"fiskerinc.com/modules/redisv2"
|
||||
)
|
||||
|
||||
func (plt *ParkLocationTracker) VCUGearSig(vin string, newState int) {
|
||||
// Fast exit if the car is not being parked
|
||||
if newState != 1 {
|
||||
return
|
||||
}
|
||||
_, ok := plt.WatchList[vin]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// WRITE park location to DB
|
||||
// DOn't want to slow down the signal processing, so do this async
|
||||
go plt.recordParkLocation(vin)
|
||||
}
|
||||
|
||||
// Probably would be better with a channel and a worker, but this is fine for now
|
||||
func (plt *ParkLocationTracker) recordParkLocation(vin string) {
|
||||
// Fetch the location from redis -- how did copilot know this?
|
||||
location, err := cachev2.GetVehicleLocation(vin, plt.RedisClient)
|
||||
if err != nil {
|
||||
logger.Err(err).Str("VIN", vin).Msg("failed to get vehicle location for park location")
|
||||
return
|
||||
}
|
||||
|
||||
// Write to DB
|
||||
_, err = plt.DBClient.GetConn().Exec("INSERT INTO towman.parked_locations (vin, latitude, longitude) VALUES (?, ?, ?)", vin, location.Latitude, location.Longitude)
|
||||
if err != nil {
|
||||
logger.Err(err).Str("VIN", vin).Msg("failed to record park location to DB")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (plt *ParkLocationTracker) UpdateVehicleList() {
|
||||
dbVINS := []string{}
|
||||
_, err := plt.DBClient.GetConn().Query(&dbVINS, "SELECT vin FROM towman.vehicles")
|
||||
if err != nil {
|
||||
logger.Err(err).Msg("failed to update parked vehicle list")
|
||||
return
|
||||
}
|
||||
// Make anew watchmap
|
||||
newWatchList := make(map[string]struct{})
|
||||
for _, vin := range dbVINS {
|
||||
newWatchList[vin] = struct{}{}
|
||||
}
|
||||
|
||||
// Only need to lock before we assign the new map
|
||||
plt.WatchListSync.Lock()
|
||||
defer plt.WatchListSync.Unlock()
|
||||
// assign watchmap
|
||||
plt.WatchList = newWatchList
|
||||
}
|
||||
|
||||
func (plt *ParkLocationTracker) IsVehicleWatched(vin string) (watched bool) {
|
||||
plt.WatchListSync.RLock()
|
||||
_, ok := plt.WatchList[vin]
|
||||
plt.WatchListSync.RUnlock()
|
||||
return ok
|
||||
}
|
||||
|
||||
func InitParkLocationTracker(dbClient *db.DBClient, redisClient *redisv2.Connection) (plt *ParkLocationTracker) {
|
||||
plt = &ParkLocationTracker{
|
||||
WatchList: make(map[string]struct{}),
|
||||
}
|
||||
plt.DBClient = dbClient
|
||||
plt.RedisClient = redisClient
|
||||
go plt.SeedDaily()
|
||||
return
|
||||
}
|
||||
|
||||
// This list won't update that often
|
||||
func (plt *ParkLocationTracker) SeedDaily() {
|
||||
plt.UpdateVehicleList()
|
||||
time.AfterFunc(time.Hour*24, plt.SeedDaily)
|
||||
}
|
||||
|
||||
type ParkLocationTracker struct {
|
||||
WatchList map[string]struct{} // VINs being tracked for parking location
|
||||
DBClient *db.DBClient
|
||||
RedisClient *redisv2.Connection
|
||||
WatchListSync sync.RWMutex
|
||||
}
|
||||
Reference in New Issue
Block a user