plushie/testing/session_pool

Shared renderer process for concurrent test sessions.

Owns a single plushie --headless --max-sessions N (or --mock) Port and multiplexes messages from multiple test sessions over it. Each session gets a unique session ID; responses are demuxed by the session field and forwarded to the owning process.

Usage

Start the pool once (typically in test setup):

let assert Ok(pool) = session_pool.start(
  session_pool.PoolConfig(..session_pool.default_config(),
    renderer_path: Some("/path/to/plushie"),
  ),
)

Then use the pooled backend, passing the pool:

let backend = pooled.backend(pool)

Types

Configuration for starting a session pool.

pub type PoolConfig {
  PoolConfig(
    mode: PoolMode,
    format: protocol.Format,
    max_sessions: Int,
    renderer_path: option.Option(String),
  )
}

Constructors

  • PoolConfig(
      mode: PoolMode,
      format: protocol.Format,
      max_sessions: Int,
      renderer_path: option.Option(String),
    )

    Arguments

    mode

    Pool mode (mock or headless). Default: Mock.

    format

    Wire format. Default: Msgpack.

    max_sessions

    Maximum concurrent sessions. Default: 8.

    renderer_path

    Path to the plushie binary. None = auto-resolve.

Pool event forwarded to session owners.

pub type PoolEvent {
  PoolEventInteractStep(
    session_id: String,
    data: dynamic.Dynamic,
  )
  PoolEventInteractResponse(
    session_id: String,
    data: dynamic.Dynamic,
  )
  PoolEventGeneric(session_id: String, data: dynamic.Dynamic)
}

Constructors

Messages the pool actor handles.

pub opaque type PoolMessage

Pool mode: mock or headless.

pub type PoolMode {
  Mock
  Headless
}

Constructors

  • Mock
  • Headless

Convenience alias for the pool actor’s Subject.

pub type PoolSubject =
  process.Subject(PoolMessage)

Reply for register calls.

pub type RegisterReply {
  Registered(session_id: String)
  PoolFull(max: Int)
  AlreadyRegistered(session_id: String)
}

Constructors

  • Registered(session_id: String)
  • PoolFull(max: Int)
  • AlreadyRegistered(session_id: String)

Reply for send-sync calls.

pub type SendReply {
  SendOk(dynamic.Dynamic)
  SendError(String)
}

Constructors

Reply for unregister calls.

pub type UnregisterReply {
  Unregistered
  UnregisterError(String)
}

Constructors

  • Unregistered
  • UnregisterError(String)

Values

pub fn default_config() -> PoolConfig

Default pool configuration.

pub fn register(pool: process.Subject(PoolMessage)) -> String

Register a new session. Returns the session ID.

pub fn send_async(
  pool: process.Subject(PoolMessage),
  session_id: String,
  msg: dict.Dict(String, node.PropValue),
) -> Nil

Send a fire-and-forget message to the renderer.

pub fn send_interact(
  pool: process.Subject(PoolMessage),
  session_id: String,
  msg: dict.Dict(String, node.PropValue),
) -> String

Send an interact message. Returns the request ID. Intermediate steps and the final response are forwarded to the session owner as PoolEvent messages.

pub fn send_message(
  pool: process.Subject(PoolMessage),
  session_id: String,
  msg: dict.Dict(String, node.PropValue),
  response_type: String,
) -> Result(dynamic.Dynamic, String)

Send a message to the renderer for the given session, waiting for a correlated response.

pub fn start(
  config: PoolConfig,
) -> Result(process.Subject(PoolMessage), actor.StartError)

Start a session pool.

pub fn unregister(
  pool: process.Subject(PoolMessage),
  session_id: String,
) -> Nil

Unregister a session.

Search Document