perf(go): cache identity binding lookups
This commit is contained in:
@@ -26,12 +26,22 @@ type MySQLResolver struct {
|
||||
db *sql.DB
|
||||
table string
|
||||
locationTouchInterval time.Duration
|
||||
lookupCacheTTL time.Duration
|
||||
lookupMu sync.Mutex
|
||||
lookupCache map[string]lookupCacheEntry
|
||||
touchMu sync.Mutex
|
||||
locationTouches map[string]time.Time
|
||||
}
|
||||
|
||||
type MySQLResolverOptions struct {
|
||||
LocationTouchInterval time.Duration
|
||||
LookupCacheTTL time.Duration
|
||||
}
|
||||
|
||||
type lookupCacheEntry struct {
|
||||
vin string
|
||||
notFound bool
|
||||
expiresAt time.Time
|
||||
}
|
||||
|
||||
func NewMySQLResolver(db *sql.DB, table string) *MySQLResolver {
|
||||
@@ -50,10 +60,16 @@ func NewMySQLResolverWithOptions(db *sql.DB, table string, opts MySQLResolverOpt
|
||||
if interval <= 0 {
|
||||
interval = 10 * time.Minute
|
||||
}
|
||||
lookupTTL := opts.LookupCacheTTL
|
||||
if lookupTTL <= 0 {
|
||||
lookupTTL = 10 * time.Minute
|
||||
}
|
||||
return &MySQLResolver{
|
||||
db: db,
|
||||
table: table,
|
||||
locationTouchInterval: interval,
|
||||
lookupCacheTTL: lookupTTL,
|
||||
lookupCache: map[string]lookupCacheEntry{},
|
||||
locationTouches: map[string]time.Time{},
|
||||
}
|
||||
}
|
||||
@@ -161,9 +177,32 @@ func (r *MySQLResolver) Resolve(ctx context.Context, env envelope.FrameEnvelope)
|
||||
}
|
||||
|
||||
func (r *MySQLResolver) lookup(ctx context.Context, column string, value string) (string, error) {
|
||||
cacheKey := column + "\x00" + value
|
||||
now := time.Now()
|
||||
r.lookupMu.Lock()
|
||||
cached, ok := r.lookupCache[cacheKey]
|
||||
if ok && now.Before(cached.expiresAt) {
|
||||
r.lookupMu.Unlock()
|
||||
if cached.notFound {
|
||||
return "", sql.ErrNoRows
|
||||
}
|
||||
return cached.vin, nil
|
||||
}
|
||||
r.lookupMu.Unlock()
|
||||
|
||||
query := "SELECT vin FROM " + r.table + " WHERE " + column + " = ? AND vin IS NOT NULL AND vin <> ''"
|
||||
var vin string
|
||||
err := r.db.QueryRowContext(ctx, query, value).Scan(&vin)
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
return "", err
|
||||
}
|
||||
r.lookupMu.Lock()
|
||||
r.lookupCache[cacheKey] = lookupCacheEntry{
|
||||
vin: strings.TrimSpace(vin),
|
||||
notFound: errors.Is(err, sql.ErrNoRows),
|
||||
expiresAt: now.Add(r.lookupCacheTTL),
|
||||
}
|
||||
r.lookupMu.Unlock()
|
||||
return vin, err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user