ExMaude.Backend.NIF (ExMaude v0.4.0)

View Source

NIF-based backend for ExMaude using Rustler.

Manages a Maude subprocess from Rust, communicating via stdin/stdout pipes through dedicated reader threads. It avoids an Erlang Port or distribution hop, but should be benchmarked with the caller's own workload. Like any NIF, the native extension shares the BEAM's OS process.

Features

  • Per-command timeouts enforced inside the NIF
  • Runs all blocking operations on the DirtyIo scheduler
  • Structured error returns (:timeout, :eof, :io_error, :lock_poisoned)

Trade-offs

  • No process isolation — a segfault in the NIF crashes the BEAM. Rustler wraps NIF entry points in std::panic::catch_unwind, so a Rust panic! becomes an Elixir exception; segfaults from unsafe code are still fatal.
  • More complex deployment than the Port backend.

Configuration

config :ex_maude,
  backend: :nif,
  max_response_bytes: 16_777_216

Getting the NIF

Published Hex packages use checksummed precompiled binaries for the supported targets below. The release pipeline generates the checksum file after the matching GitHub release assets exist and before publishing the package.

A source checkout intentionally has an empty checksum file, so development builds must opt into compilation from source (requires a Rust toolchain):

EX_MAUDE_BUILD=1 mix compile --force        # in this project
EX_MAUDE_BUILD=1 mix deps.compile ex_maude  # as a dependency

Use :port as the default when a precompiled NIF is unavailable and a local Rust build is not desired.

Summary

Types

t()

Internal state for the NIF backend GenServer.

Functions

Checks if the NIF backend is alive.

Returns a specification to start this module under a supervisor.

Executes a Maude command via NIF.

Loads a Maude file via NIF.

Starts the NIF backend worker.

Stops the NIF backend worker.

Types

t()

@type t() :: %ExMaude.Backend.NIF{
  handle: reference() | nil,
  maude_path: String.t() | nil,
  max_response_bytes: pos_integer()
}

Internal state for the NIF backend GenServer.

Functions

alive?(server)

@spec alive?(GenServer.server()) :: boolean()

Checks if the NIF backend is alive.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

execute(server, command, opts \\ [])

@spec execute(GenServer.server(), String.t(), keyword()) ::
  {:ok, String.t()} | {:error, term()}

Executes a Maude command via NIF.

Options

  • :timeout - Maximum time to wait in milliseconds (default: 30000)

load_file(server, path)

@spec load_file(GenServer.server(), Path.t()) :: :ok | {:error, term()}

Loads a Maude file via NIF.

Options

  • :timeout - Maximum time to wait in milliseconds (default: 30000)

start_link(opts \\ [])

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

Starts the NIF backend worker.

Options

  • :maude_path - Path to Maude executable (optional, auto-detected)

stop(server)

@spec stop(GenServer.server()) :: :ok

Stops the NIF backend worker.