# `Zizq.BudgetBinding`
[🔗](https://github.com/zizq-labs/zizq-elixir/blob/v0.8.0/lib/zizq/budget_binding.ex#L4)

A job's claim on a budget: which budget, and what it costs to
dispatch.

    Zizq.BudgetBinding.new!(key: "emails", cost: 2)

Bindings are passed to the server as part of the enqueue operation,
and so usually declared on a job module:

    defmodule MyApp.SendEmail do
      use Zizq.JobKind,
        type: "send_email",
        queue: "emails",
        budgets: [[key: "emails", cost: 2]]

      @impl Zizq.JobKind
      def perform(payload), do: MyApp.Mailer.deliver(payload)
    end

## `:cost`

How many tokens one job debits from the budget when it dispatches,
defaulting to `1`. Jobs can therefore weigh differently against the
same budget — a bulk send costing `10` against an allocation of `100`
leaves room for 90 more single sends.

A cost has to fit inside the budget's `Zizq.Budget.capacity/1`, or the
job would forever be held back from dispatching. The server refuses a
binding that does not satisfy the invariant.

## `:create_with`

Declares the budget's policy should it not exist yet, so binding and
creating happen in one atomic request rather than over two:

    Zizq.BudgetBinding.new!(
      key: "emails",
      cost: 2,
      create_with: [
        allocation: 100,
        strategy: :time_based,
        duration: :timer.minutes(1)
      ]
    )

The key comes from the binding, so it is not repeated. It is ignored
when the budget already exists — the server stays authoritative.

Without it, the budget has to exist before a job can bind to it.

# `t`

```elixir
@type t() :: %Zizq.BudgetBinding{
  cost: pos_integer() | nil,
  create_with: Zizq.Budget.t() | nil,
  key: String.t()
}
```

# `new!`

```elixir
@spec new!(t() | keyword() | map()) :: t()
```

Build a binding from a keyword list or map. Raises on invalid input.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
