Manifest (Manifest v0.3.2) View Source

Provides a structure for ordering operations that need to happen, and how to roll them back if they fail.

There are examples of usage in test/example_test.exs.

Link to this section Summary

Functions

Adds either the first step or the second based on the truthy-ness of the given conditional function.

Adds a Manifest.Step to the :steps key of the manifest.

Reports on the results of perform/1.

Check if any of the steps had an error.

Initializes a new t:Manifest.t().

Performs the steps in the order given to the manifest.

Rolls back each operation in case of failure.

Link to this section Types

Specs

t() :: %Manifest{
  errored: Manifest.Step.operation(),
  halt?: boolean(),
  previous: map(),
  reason: any(),
  rollbacks: [Manifest.Step.rollback()],
  steps: [Manifest.Step.t()]
}

Link to this section Functions

Link to this function

add_branch(manifest, branch)

View Source
This function is deprecated. Use Manifest.merge/2 instead.

Specs

add_branch(t(), Manifest.Branch.t()) :: t()

Adds either the first step or the second based on the truthy-ness of the given conditional function.

Link to this function

add_step(manifest, step)

View Source

Specs

add_step(t(), Manifest.Step.t()) :: t()

Adds a Manifest.Step to the :steps key of the manifest.

True to Elixir/Erlang practices, it is prepended to the list. The list is reversed the work is actually performed.

Link to this function

add_step(manifest, operation, work, rollback \\ &Step.safe_default_rollback/2, parser \\ &Step.default_parser/1)

View Source

Specs

Combines build_step/4 and add_step/2 into one function.

See add_step/2 for more information on how the steps are added and Manifest.Step for more information on what a step consists of.

Link to this function

build_branch(conditional, success, failure)

View Source
This function is deprecated. Use Manifest.merge/2 instead.

Specs

Link to this function

build_step(operation, work, rollback \\ &Step.safe_default_rollback/2, parser \\ &Step.default_parser/1)

View Source

Specs

Builds a t:Manifest.Step.t() from the given parameters.

See Manifest.Step for more information on what a step consists of.

Specs

digest(t()) :: {:ok, map()} | {:error, atom(), any(), map()}

Reports on the results of perform/1.

Returns an :ok tuple with the value of the :previous key which contains the results of all the steps if all steps succeeded. Otherwise it returns an :error tuple with the Manifest.Step.operation/0, as it's second element, the results of that step's Manifest.Step.work/0, and the value of the :previous field at the time of failure. (Which, since all other work is halted, means the summary of work done.) It works essentially the same as the return of Ecto.Repo.transaction/1 when given an Ecto.Multi.

Specs

errored?(t()) :: boolean()

Check if any of the steps had an error.

Specs

new() :: t()

Initializes a new t:Manifest.t().

The manifest is not customizable, so no options can be given to this function.

Specs

perform(t()) :: t()

Performs the steps in the order given to the manifest.

(Each new call of add_step/1 prepends a Manifest.Step.t/0 to the list, then the list is reversed before performing.) If a step's Manifest.Step.work/0 succeeds without returning :no_rollback in the tuple, the Manifest.Step.parser/0 finds the identifier, and a Manifest.Step.rollback/0 is defined the rollback will be added to the :rollbacks stack. If a step fails, the :halt? will activate and no further work will be performed. The :errored key will be set to the operation that triggered the failure. Whether or not the step fails, a key-value pair will be added to the :previous field. The Manifest.Step.operation/0 will be the key of that key-value pair.

TL;DR: There's three paths a step can take:

  1. It returns {:ok, term} in which case it will add a rollback to the stack.
  2. It returns {:ok, :no_rollback, term} where no rollback will be added.
  3. It returns {:error, term} which will halt the Manifest and no further steps will be performed. You can then choose to roll it all back where it will pop the functions off the stack.

See digest/1 as it provides an easier way of extracting pertinent information on what happened during this function.

Specs

rollback(t()) :: {:ok, map()} | {:error, atom(), any(), map()}

Rolls back each operation in case of failure.

Each Manifest.Step.t/0 that ran previous to the point of failure, defines a Manifest.Step.rollback/0 in the manifest, and didn't receive a :no_rollback in tuple that the step's Manifest.Step.work/0 returned, will be rolled back in reverse from the order the steps were performed. If any of the rollbacks fail, it stops attempting to roll back and returns an :error tuple. The error tuple has the Manifest.Step.operation/0 where it failed as it's second element, the reason as the third, and a map containing the results of all the successful roll backs up to that point.

You can also call rollback/1 on a completely successful Manifest.