Skip to content

Redis session store: Session struct contains non-serializable fields (PIDs, atoms) #60

@emilwojtaszek

Description

@emilwojtaszek

Problem

When using the Redis session store, sessions fail to serialize because Anubis.Server.Session contains non-serializable fields:

** (Protocol.UndefinedError) protocol Jason.Encoder not implemented for #PID<0.123.0>

The name field in the Session struct can be:

  • A PID (e.g., #PID<0.123.0>)
  • An atom (e.g., :my_server)
  • A tuple (e.g., {:via, Registry, {MyRegistry, "key"}})

These are valid GenServer.name() types but cannot be JSON-encoded.

Current Workaround

I had to implement a custom Jason.Encoder for Anubis.Server.Session:

defimpl Jason.Encoder, for: Anubis.Server.Session do
  def encode(session, opts) do
    %{
      id: session.id,
      protocol_version: session.protocol_version,
      initialized: session.initialized,
      name: nil,  # PIDs can't be deserialized anyway
      client_info: session.client_info,
      client_capabilities: session.client_capabilities,
      log_level: session.log_level,
      pending_requests: session.pending_requests
    }
    |> Jason.Encode.map(opts)
  end
end

This works because:

  1. PIDs/atoms can't be meaningfully restored after a restart anyway
  2. The name is reset when the session is restored (see session.ex restore logic)

Questions

  1. Should Anubis.Server.Session implement Jason.Encoder natively in the library?
  2. Or should the Redis store handle serialization differently (e.g., using :erlang.term_to_binary instead of JSON)?
  3. Is there a better approach I'm missing?

Environment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions