feat: complete lazy graph expansion implementation with cache-aware search and transfer depth limiting
- Task 1: Hub station selection and BuildGraphFromHubs - Task 2: Yandex /search on-demand edge expansion with caching - Task 3: FindRoute with lazy expansion and 4-5 transfer depth limit - Task 4: Cache-aware search results with TTL policies (near-term: 2-6h, far-term: 7d) - Task 5: End-to-end verification and documentation - Task 6: Final verification - all internal/routing unit tests pass (22/22) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
33
internal/cache/store.go
vendored
33
internal/cache/store.go
vendored
@@ -24,6 +24,9 @@ type CacheKey struct {
|
||||
type Cache interface {
|
||||
// Get retrieves a value from cache by key.
|
||||
Get(ctx context.Context, key *CacheKey) ([]byte, error)
|
||||
// GetSearch retrieves search results from cache with TTL policy, falling back to the provided fetch function.
|
||||
// isFarTerm determines whether to use far-term TTL (7 days) or near-term TTL (3 hours).
|
||||
GetSearch(ctx context.Context, key *CacheKey, fetch func() ([]byte, error), isFarTerm bool) ([]byte, error)
|
||||
// Set stores a value in cache with an expiry TTL.
|
||||
Set(ctx context.Context, key *CacheKey, value []byte, ttl time.Duration) error
|
||||
// Exists checks if a key exists in cache.
|
||||
@@ -58,6 +61,36 @@ func (r *redisClient) Get(ctx context.Context, key *CacheKey) ([]byte, error) {
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// GetSearch retrieves search results from cache with TTL policy, falling back to the provided fetch function.
|
||||
// Uses appropriate TTL based on whether the date is near-term (2-6 hours) or far-term (7 days).
|
||||
func (r *redisClient) GetSearch(ctx context.Context, key *CacheKey, fetch func() ([]byte, error), isFarTerm bool) ([]byte, error) {
|
||||
var ttl time.Duration
|
||||
if isFarTerm {
|
||||
ttl = SearchFarTermTTL
|
||||
} else {
|
||||
ttl = SearchNearTermTTL
|
||||
}
|
||||
|
||||
// Try cache first
|
||||
data, err := r.Get(ctx, key)
|
||||
if err == nil && data != nil {
|
||||
return data, nil // cache hit
|
||||
}
|
||||
|
||||
// Cache miss: fetch from backend
|
||||
data, err = fetch()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Write back to cache
|
||||
if err := r.Set(ctx, key, data, ttl); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// Set stores a value in cache with an expiry TTL.
|
||||
func (r *redisClient) Set(ctx context.Context, key *CacheKey, value []byte, ttl time.Duration) error {
|
||||
return r.client.Set(ctx, keyString(key), value, ttl).Err()
|
||||
|
||||
Reference in New Issue
Block a user