Phoenix.SessionProcess.ActivityTracker (phoenix_session_process v1.0.1)

Copy Markdown View Source

Tracks session activity timestamps for TTL-based cleanup.

This module maintains an ETS table that records the last activity time for each session. This enables intelligent cleanup that only removes truly idle sessions, not sessions that are actively being used.

Usage

The activity tracker is automatically initialized when the supervision tree starts. Activity is tracked automatically during session operations:

  • Session start: Initial activity recorded
  • Call operations: Activity updated
  • Cast operations: Activity updated
  • Manual touch: Activity updated via touch/1

Cleanup Integration

The Cleanup process uses this tracker to determine which sessions have expired based on inactivity rather than just creation time.

Performance

  • ETS table with :set type for O(1) lookups
  • Public table for concurrent access
  • Read concurrency enabled for high-performance reads
  • Minimal memory overhead (only session_id + timestamp)

Example

# Touch a session to update its activity
ActivityTracker.touch("session_123")

# Get last activity time
{:ok, timestamp} = ActivityTracker.get_last_activity("session_123")

# Check if session is expired
expired? = ActivityTracker.expired?("session_123", ttl: 3_600_000)

Summary

Functions

Removes all activity tracking data. Useful for testing.

Returns the total number of tracked sessions.

Checks if a session has expired based on its last activity.

Gets all sessions that have expired.

Gets the last activity timestamp for a session.

Initializes the activity tracker ETS table. This is called automatically during application startup.

Removes activity tracking for a session. Called automatically when a session terminates.

Records or updates the last activity time for a session.

Functions

clear()

@spec clear() :: :ok

Removes all activity tracking data. Useful for testing.

Examples

iex> ActivityTracker.clear()
:ok

count()

@spec count() :: non_neg_integer()

Returns the total number of tracked sessions.

Examples

iex> ActivityTracker.count()
42

expired?(session_id, opts \\ [])

@spec expired?(binary(), keyword()) :: boolean()

Checks if a session has expired based on its last activity.

A session is considered expired if:

  • It has no recorded activity (returns false - assume newly created)
  • Its last activity was more than TTL milliseconds ago (returns true)

Options

  • :ttl - Time-to-live in milliseconds (defaults to configured session_ttl)

Examples

iex> ActivityTracker.touch("session_123")
iex> ActivityTracker.expired?("session_123", ttl: 3_600_000)
false

# After 2 hours
iex> ActivityTracker.expired?("session_123", ttl: 3_600_000)
true

get_expired_sessions(opts \\ [])

@spec get_expired_sessions(keyword()) :: [binary()]

Gets all sessions that have expired.

Returns a list of session IDs that haven't been active within the TTL window.

Options

  • :ttl - Time-to-live in milliseconds (defaults to configured session_ttl)

Examples

iex> expired_sessions = ActivityTracker.get_expired_sessions(ttl: 3_600_000)
["session_1", "session_2"]

get_last_activity(session_id)

@spec get_last_activity(binary()) :: {:ok, integer()} | {:error, :not_found}

Gets the last activity timestamp for a session.

Returns {:ok, timestamp} if found, or {:error, :not_found} if the session has no recorded activity.

Examples

iex> ActivityTracker.touch("session_123")
iex> ActivityTracker.get_last_activity("session_123")
{:ok, 1234567890}

iex> ActivityTracker.get_last_activity("nonexistent")
{:error, :not_found}

init()

@spec init() :: :ok

Initializes the activity tracker ETS table. This is called automatically during application startup.

remove(session_id)

@spec remove(binary()) :: :ok

Removes activity tracking for a session. Called automatically when a session terminates.

Examples

iex> ActivityTracker.remove("session_123")
:ok

touch(session_id)

@spec touch(binary()) :: :ok

Records or updates the last activity time for a session.

Examples

iex> ActivityTracker.touch("session_123")
:ok