test(pubsub): stop racing the Redis SUBSCRIBE ack (#38661)

`RedisBroker.Subscribe` returns before the server acks `SUBSCRIBE`, so a
publish right after it can be dropped, making
`TestRedisBroker/CrossBroker` fail intermittently on loaded CI runners
([example](https://github.com/go-gitea/gitea/actions/runs/30257188479/job/89948425118)).

Each scenario now uses its own topic and waits for `PUBSUB NUMSUB`
before publishing. `MemoryBroker` registers synchronously and skips the
wait.
This commit is contained in:
silverwind
2026-07-27 16:12:06 +02:00
committed by GitHub
parent 341caf8aa7
commit 7efcb8d6ca
3 changed files with 48 additions and 22 deletions
+4 -2
View File
@@ -94,8 +94,10 @@ func (b *RedisBroker) Subscribe(topic string) (<-chan []byte, func()) {
// other Subscribe/cancel calls aren't blocked on the network round-trip.
// graceful.ShutdownContext so the reader loop dies cleanly on Gitea
// shutdown even if every local subscriber has already cancelled.
// readLoop consumes the SUBSCRIBE ack; don't wait for it here, a direct
// ps.Receive blocks for its whole timeout instead of returning on the ack.
// readLoop consumes the SUBSCRIBE ack; don't wait for it here, that would put
// a Redis round-trip in the WebSocket handshake to close a sub-millisecond
// window in which a publish is missed - harmless, since a client receives
// nothing at all until its handshake completes.
ctx, cancelCtx := context.WithCancel(graceful.GetManager().ShutdownContext())
ps := b.client.Subscribe(ctx, redisChannelForTopic(topic))
b.mu.Lock()