Phoenix.SocketClient.RouteCache (phoenix_socket_client v0.8.0)

View Source

High-performance ETS-based caching for message routing.

This module provides an ETS-based cache for storing and retrieving channel process PIDs by topic, significantly improving message routing performance compared to Registry lookups.

Features

  • ETS-based O(1) lookups for channel routing
  • Automatic cache invalidation and cleanup
  • Memory-efficient storage with TTL support
  • Statistics and monitoring capabilities
  • Cache warming strategies

Usage

The route cache is automatically started by the socket supervisor and provides fast channel-to-process mapping for message routing.

Performance Benefits

  • Eliminates Registry overhead for frequent lookups
  • Provides constant-time routing operations
  • Reduces process discovery latency
  • Handles high-frequency message routing efficiently

Summary

Types

Cache entry with metadata

Cache configuration options

t()

Route cache state

Functions

Checks if a topic is cached.

Returns a specification to start this module under a supervisor.

Clears all cached routes.

Removes a route from the cache.

Gets a channel PID from the cache.

Puts a route mapping in the cache.

Starts the route cache server.

Gets cache statistics for monitoring.

Warms up the cache with common routes.

Types

cache_entry()

@type cache_entry() :: %{
  pid: pid(),
  timestamp: integer(),
  access_count: non_neg_integer(),
  last_access: integer()
}

Cache entry with metadata

opts()

@type opts() :: [
  cache_size: non_neg_integer(),
  ttl: non_neg_integer(),
  cleanup_interval: non_neg_integer(),
  registry_name: atom()
]

Cache configuration options

t()

@type t() :: %Phoenix.SocketClient.RouteCache{
  cache_size: non_neg_integer(),
  cache_table: :ets.tid(),
  cleanup_interval: non_neg_integer(),
  cleanup_timer: reference() | nil,
  registry_name: atom() | nil,
  stats: %{
    hits: non_neg_integer(),
    misses: non_neg_integer(),
    evictions: non_neg_integer(),
    insertions: non_neg_integer(),
    current_size: non_neg_integer()
  },
  ttl: non_neg_integer()
}

Route cache state

Functions

cached?(cache_pid, topic)

@spec cached?(pid(), String.t()) :: boolean()

Checks if a topic is cached.

Returns true if the topic exists in cache, false otherwise.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

clear(cache_pid)

@spec clear(pid()) :: :ok

Clears all cached routes.

Useful for cache invalidation or testing.

delete(cache_pid, topic)

@spec delete(pid(), String.t()) :: :ok

Removes a route from the cache.

Useful when a channel leaves or terminates.

get(cache_pid, topic)

@spec get(pid(), String.t()) :: {:ok, pid()} | :error

Gets a channel PID from the cache.

Returns {:ok, pid} if found and valid, :error otherwise.

put(cache_pid, topic, channel_pid)

@spec put(pid(), String.t(), pid()) :: :ok

Puts a route mapping in the cache.

Associates a topic with a channel PID.

start_link(opts \\ [])

@spec start_link(opts()) :: GenServer.on_start()

Starts the route cache server.

Options

  • :cache_size - Maximum number of cached routes (default: 1000)
  • :ttl - Time-to-live for cache entries in milliseconds (default: 300000)
  • :cleanup_interval - Cleanup interval for expired entries (default: 60000)
  • :registry_name - Registry name for fallback lookups

stats(cache_pid)

@spec stats(pid()) :: map()

Gets cache statistics for monitoring.

Returns detailed performance and usage statistics.

warm_up(cache_pid, routes)

@spec warm_up(pid(), [{String.t(), pid()}]) :: :ok

Warms up the cache with common routes.

Pre-populates the cache with known channel mappings.