Malachi.Cluster.RebalanceCoordinator (malachi v0.22.7)

View Source

The manual plan/commit coordinator for dynamic rebalancing (R3-b). An operator calls plan/1 to see the changes that would move each vnode to the placement desired over the live membership, then commit/1 to apply them. Commit is never automatic, nothing moves until the operator asks.

It is a GenServer so commits serialize (one at a time) and it holds the wiring; the world is reached through seams, so it is testable without ra or a real lease:

  • :plan_fun - (-> plan), the current rebalancing plan (wired to Malachi.Application.live_rebalance_plan/5);
  • :add_member / :remove_member - the Malachi.Cluster.Rebalance member ops (wired to ra_*);
  • :leader? - (-> boolean()), whether this node currently holds the lease (wired to the LeaseHolder); commit/1 refuses unless it holds the lease, and passes this same check to Rebalance.apply_plan/4 so a lease lost mid-commit stops the run.
  • :name - optional registered name.

commit/1 returns Rebalance.apply_plan/4's result ({:ok, applied} / {:error, {applied, failure}}) or {:error, :not_leader} when this node does not hold the lease.

Summary

Functions

Returns a specification to start this module under a supervisor.

Commits the current plan under the lease: refuses with {:error, :not_leader} unless this node holds the lease, otherwise runs Rebalance.apply_plan/4 fail-fast. May take a while (it moves vnodes), so it uses an infinite call timeout and serializes with other commits.

The rebalancing plan for the live cluster (computes, does not apply).

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

commit(server)

@spec commit(GenServer.server()) ::
  {:ok, [atom()]}
  | {:error, {[atom()], Malachi.Cluster.Rebalance.failure()}}
  | {:error, :not_leader}

Commits the current plan under the lease: refuses with {:error, :not_leader} unless this node holds the lease, otherwise runs Rebalance.apply_plan/4 fail-fast. May take a while (it moves vnodes), so it uses an infinite call timeout and serializes with other commits.

plan(server)

The rebalancing plan for the live cluster (computes, does not apply).

start_link(opts)

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