RedisServerWrapper.Server (redis_server_wrapper v0.7.3)

Copy Markdown View Source

GenServer managing a single redis-server process.

Starts redis-server with a generated config file, tracks the OS PID, and sends SHUTDOWN NOSAVE on terminate (unless detached).

Usage

{:ok, pid} = RedisServerWrapper.Server.start_link(port: 6400, password: "secret")
RedisServerWrapper.Server.ping(pid)
RedisServerWrapper.Server.run(pid, ["SET", "key", "value"])
RedisServerWrapper.Server.stop(pid)

Options

All options from RedisServerWrapper.Config are supported, plus:

  • :redis_server_bin - path to redis-server binary (default: "redis-server")
  • :redis_cli_bin - path to redis-cli binary (default: "redis-cli")
  • :name - GenServer name registration
  • :timeout - startup timeout in ms (default: 10_000)
  • :loadmodule - Redis modules to load; accepts module paths or {path, [args]} tuples (default: [])
  • :managed - controls how the redis-server OS process is tied to the BEAM:
    • true (default) - redis-server runs as a Port tied to the BEAM lifecycle. When the BEAM exits, the port closes and redis-server receives SIGHUP. Teardown runs in terminate/2, which is skipped on a :brutal_kill supervisor shutdown or a hard BEAM death, so the OS process can be stranded.
    • :forcola - redis-server runs in the foreground under a Forcola.Daemon, which guarantees the OS process group is killed and confirmed dead on owner death or supervisor shutdown, including the paths where terminate/2 never runs. Requires the optional :forcola dependency ({:forcola, "~> 0.3"}); start_link returns {:error, :forcola_not_available} if it is missing.
    • false - redis-server daemonizes independently (legacy behavior); the caller owns the OS process lifecycle.

Summary

Functions

Returns true if the redis-server OS process is still alive.

Returns a specification to start this module under a supervisor.

Returns the Cli struct for direct use.

Returns the default redis-server binary path. Prefers the actual redis-server binary from redis-stack (includes modules) over the wrapper script, then falls back to plain redis-server.

Detaches the server -- the redis-server OS process will NOT be stopped when this GenServer terminates. Returns {:error, :managed_server} in managed mode.

Returns connection info: host, port, password, pid, node_dir.

Pings the server. Returns true if alive.

Runs an arbitrary redis-cli command against this server.

Starts a redis-server process without linking.

Starts and links a redis-server process.

Gracefully stops the GenServer (which stops redis-server unless detached).

Types

managed()

@type managed() :: boolean() | :forcola

t()

@type t() :: %RedisServerWrapper.Server{
  cli: RedisServerWrapper.Cli.t(),
  config: RedisServerWrapper.Config.t(),
  daemon: pid() | nil,
  detached: boolean(),
  managed: managed(),
  node_dir: String.t() | nil,
  pid: non_neg_integer() | nil,
  port_ref: port() | nil,
  redis_server_bin: String.t()
}

Functions

alive?(server)

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

Returns true if the redis-server OS process is still alive.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

cli(server)

Returns the Cli struct for direct use.

default_server_bin()

@spec default_server_bin() :: String.t()

Returns the default redis-server binary path. Prefers the actual redis-server binary from redis-stack (includes modules) over the wrapper script, then falls back to plain redis-server.

We avoid the redis-stack-server bash wrapper because it overrides our dir config with its own --dir flag, causing cluster config files to end up in the wrong place. Instead, we use the real binary directly.

detach(server)

@spec detach(GenServer.server()) :: :ok | {:error, :managed_server}

Detaches the server -- the redis-server OS process will NOT be stopped when this GenServer terminates. Returns {:error, :managed_server} in managed mode.

info(server)

@spec info(GenServer.server()) :: map()

Returns connection info: host, port, password, pid, node_dir.

ping(server)

@spec ping(GenServer.server()) :: boolean()

Pings the server. Returns true if alive.

run(server, args)

@spec run(GenServer.server(), [String.t()]) ::
  {:ok, String.t()} | {:error, String.t()}

Runs an arbitrary redis-cli command against this server.

start(opts \\ [])

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

Starts a redis-server process without linking.

start_link(opts \\ [])

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

Starts and links a redis-server process.

stop(server)

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

Gracefully stops the GenServer (which stops redis-server unless detached).