Resolves each shard topic's replica broker IDs (internal/kafka.Admin.
ReplicaBrokerIDs) to the topology.kubernetes.io/zone labels of the nodes
hosting those brokers (ZoneLocator), and writes the result into
ShardStatus.AvailabilityZones each reconcile. Uses mgr.GetAPIReader()
rather than the cached client for the Pod/Node lookups, since the cached
client would otherwise require cluster-wide list/watch RBAC on Pods just
to serve occasional point Gets.
main.go called Reconcile(ctx, req.Name) without req.Namespace, so the
Get against the namespaced Queue CRD always 404'd and was silently
swallowed as success -- no shard topics or Redis state were ever created.
Separately, ShardStatus.HashRangeStart/End were uint32, but controller-gen
maps that to OpenAPI format:int32, whose max (2147483647) is smaller than
FullHashRangeEnd (0xFFFFFFFF), so the apiserver rejected every status
update with the (misleadingly empty-looking) "must be of type integer with
format int32" error. Widened to int64, regenerated the CRD, and synced the
chart's bundled copy.
Assembles tasks 1/6/7/8 into a runnable cmd/server binary: QueueServiceServer
handlers translating kafkamgmt.v1 proto to internal/core/queue's plain Go
types, a lazy per-queue Kafka consumer registry for ReceiveMessage, and a
Redis-scan-based queue discovery loop that starts a reaper goroutine per
queue (queue lifecycle isn't exposed over gRPC, so this is the server's only
signal). Promotes kmsvc-proto to a direct go.mod dependency.
Handler-level integration tests run against kfake+miniredis (same documented
tradeoff as tasks 5-7's envtest/testcontainers substitution), exercising
send->receive->delete through the real QueueServiceServer implementation.
Remove local proto/, buf.yaml, buf.gen.yaml, and generated
internal/api/v1/*.pb.go. The message-plane contract now lives in the
sibling repo kmsvc-proto (forgejo.riotpiao.homelab.com/rock/kmsvc-proto),
fetched via go get — no local buf/protoc plugin install needed.
Nothing in this repo imported internal/api/v1 yet, so this is a clean
swap with no call-site changes.
JWKS caching via lestrrat-go/jwx, signature/iss/aud/exp validation, and
a single gRPC interceptor that grpc-gateway's forwarded headers make
work identically for REST callers.
Per-queue ticker that scans vis_index for expired in-flight messages and
drives each through the atomic reap.lua check-and-act, routing maxed-out
messages to their queue's configured DLQ via the existing SendMessage
path. Safe to run from multiple replicas against the same queue.
Implements SendMessage (size cap, FIFO dedup, shard routing), ReceiveMessage
(long-poll loop across active+closing shards, FIFO per-group exclusivity
gating, redelivery hand-out), DeleteMessage (ack + low-watermark offset
advancement), and ChangeMessageVisibility against the Redis state layer
and a real Kafka producer/consumer.
Reconciles Queue CRs into Kafka topics + Redis shard-map/queue-meta state:
creates shard-0 on first reconcile, splits a shard's hash range into two
children once its split threshold is crossed, drains and closes a parent
shard once its consumer group has fully caught up and its retention
window has elapsed, and tears down every shard's topic + Redis state on
deletion. Includes the manager entrypoint (cmd/queue-operator) and RBAC.
Implements the kmsvc: key schema (inflight, pending/watermark keyed by
shard+partition, vis_index, dedup, fifo_lock, queue meta, shard map) plus
the atomic reap/ack Lua scripts used for safe multi-replica redelivery
and DLQ routing.
Adds queue_service.proto (SendMessage, SendMessageBatch, ReceiveMessage,
DeleteMessage, DeleteMessageBatch, ChangeMessageVisibility(Batch)) with
grpc-gateway REST annotations, plus the generated Go server/client and
gateway stubs.