mirror of
https://github.com/hanzoai/ha.git
synced 2026-09-30 22:38:49 +00:00
HRW (Rendezvous) single-writer election as its own coordination primitive — no coordinator, lock service, Postgres, or Redis. Answers "who is the single writer for key K" identically on every replica. Extracted from hanzoai/vfs/replica/owner.go (HIP-0107), which was storage-agnostic pure Go with no vfs-internal callers. Election (who writes) and replication (how state ships) are orthogonal; this is the cut. Generalizes orgID -> key (any ownership unit). API: Member, Owner, IsOwner, Replicas + the Membership seam + Static. Zero deps (stdlib crypto/sha256, encoding/binary, context).
33 lines
909 B
Go
33 lines
909 B
Go
// Copyright 2025 Hanzo AI Inc. All Rights Reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
package ha
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
)
|
|
|
|
// TestStaticIsSelfOwner proves single-process Membership always elects itself: the
|
|
// sole member owns every key, so a standalone binary is exactly-once by construction.
|
|
func TestStaticIsSelfOwner(t *testing.T) {
|
|
m := Static("solo")
|
|
if m.Self() != "solo" {
|
|
t.Fatalf("Self()=%q, want solo", m.Self())
|
|
}
|
|
members, err := m.Members(context.Background())
|
|
if err != nil {
|
|
t.Fatalf("Members: %v", err)
|
|
}
|
|
if len(members) != 1 || members[0].ID != "solo" {
|
|
t.Fatalf("Members=%v, want [{solo}]", members)
|
|
}
|
|
for _, key := range []string{"a", "b", "c"} {
|
|
if !IsOwner(key, m.Self(), members) {
|
|
t.Fatalf("static member must own every key; missed %q", key)
|
|
}
|
|
}
|
|
}
|