Skip to content

Optional short-lived client-side caching to reduce redundant API calls #85

@GustavoCaso

Description

@GustavoCaso

Add an optional in-memory cache with a configurable TTL to the Docker client wrapper, preventing redundant API calls during rapid refreshes or simultaneous section refreshes.

Current State

  • Every refresh hits the Docker API with no caching
  • ctrl+r (global refresh) triggers all 4 sections to refresh simultaneously, causing 4+ parallel API calls
  • The auto-refresh interval can be set as low as desired, potentially hammering the daemon

Proposed Approach

1. Create a caching wrapper

In internal/client/cached_client.go, create a CachedClient that wraps a real Client:

type CachedClient struct {
    inner  Client
    ttl    time.Duration
    cache  map[string]cacheEntry
    mu     sync.RWMutex
}
type cacheEntry struct {
    value     any
    expiresAt time.Time
}

2. Cache list responses

Cache responses for ListContainers, ListImages, ListVolumes, ListNetworks with the configured TTL. Cache key = method name + serialized options.

3. Bypass cache for mutations

All write operations (start, stop, delete, create, etc.) bypass the cache and also invalidate the relevant cache keys so the next read gets fresh data.

4. Make it configurable

In internal/config/config.go, add:

[cache]
enabled = true
ttl = "1s"

5. Wire into app startup

In cmd/docker-dash/main.go, wrap the real client with CachedClient if caching is enabled in config.

Acceptance Criteria

  • List calls within the TTL window return cached results without a Docker API call
  • Mutation operations bypass and invalidate the cache
  • Cache is disabled by default (opt-in)
  • TTL is configurable in config.toml
  • No data races (proper sync.RWMutex usage)
  • Linter and race detector (make test-race) pass

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestp4Code quality and architecture

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions