MishkaCmsCore.Isolated (Mishka CMS Core v0.0.1)

Copy Markdown View Source

Runs one function in a separate operating-system process: a peer BEAM started for the call (:peer, in OTP's stdlib) and stopped after it.

For work done by native code that could take the server down with it: a NIF that crashes on a malformed file ends the whole BEAM, and no supervisor can catch that. Run through run/4, the crash ends the peer, and the caller gets {:error, reason} back. Every site keeps serving.

{:ok, png} = Isolated.run(MyApp.Thumbnail, :draw, [path])
{:error, _reason} = Isolated.run(:erlang, :halt, [139])

What the peer has

The caller's code path (:code.get_path/0), so every module of the release or the project is there to call; no application is started, and no configuration is loaded. function starts what it needs.

It is the same Erlang the caller runs: the erl of its own ERTS, booted with the start_clean boot file beside the caller's own — in a release releases/<version>/start_clean, with its RELEASE_LIB — so it starts the same in development and in a release, with nothing on PATH.

Options

  • :timeout — milliseconds to wait for the answer, default 30_000; past it the peer is killed and the answer is {:error, :timeout}
  • :env — [{name, value}] of charlists for the peer's environment; false as the value removes a variable the caller has
  • :nice — 0..19, the peer's scheduling priority below the caller's, given to it by the system's nice (/usr/bin/nice or /bin/nice); default 0. Where neither is there, the peer runs at the caller's priority

Answers

{:ok, result} with what function returned, else {:error, reason}: it raised, it exited, the peer died, or it took too long. The caller is never linked to the peer, so nothing it does can end the caller.

Summary

Types

option()

@type option() ::
  {:timeout, timeout()}
  | {:env, [{charlist(), charlist() | false}]}
  | {:nice, 0..19}

Functions

run(module, function, args, opts \\ [])

@spec run(module(), atom(), list(), [option()]) :: {:ok, term()} | {:error, term()}