TaskRing

class TaskRing(peers: Set<PeerId>, val vnodeCount: Int = 150, seed: Long = 0)

A consistent-hash ring that assigns tasks to peers in a deterministic, balanced way.

The ring IS the roster. Given a snapshot of the current peer set, every node computes the same ring and the same task-to-peer mapping — no coordination required. Tasks are assigned by finding the first peer clockwise of the task's hash position on the ring.

Virtual nodes — each peer occupies vnodeCount positions on the ring. More virtual nodes → more even load distribution at the cost of a slightly larger ring. 150 is a good default for groups up to ~20 peers.

Failover — when an owner becomes unreachable, call successor with the owner (and any other down peers) in the excluding set. The next peer clockwise that is not excluded becomes the failover owner deterministically.

Pluggable roster — construct via RosterSnapshot.toTaskRing to bind to a specific roster source. Two sources are available out of the box:

  • Raft voter membership (strong consistency, zero steady-state dups)

  • Session room roster (eventual consistency, cheaper for low-churn groups)

This class is pure and synchronous — it holds a snapshot; callers rebuild it when the roster changes.

Parameters

peers

The current peer roster. Empty → owner always returns null.

vnodeCount

Virtual nodes per peer. Default 150.

seed

Deterministic seed for vnode placement. Use a stable constant across all nodes in the same session so every node produces the same ring.

Constructors

Link copied to clipboard
constructor(peers: Set<PeerId>, vnodeCount: Int = 150, seed: Long = 0)

Properties

Link copied to clipboard

Functions

Link copied to clipboard
fun owner(taskId: TaskId): PeerId?

Returns the peer that owns taskId under the current roster, or null if the roster is empty.

fun owner(taskId: TaskId, eligible: Set<PeerId>): PeerId?

Returns the owner of taskId restricted to the eligible subset of the roster, or null if no ring peer is eligible.

Link copied to clipboard
fun successor(taskId: TaskId, excluding: Set<PeerId>): PeerId?

Returns the first peer clockwise of taskId's position that is NOT in excluding, or null if all roster peers are excluded.