A message that reaches a builder's subscription outside a fetch was held unheartbeated for the whole run of another ask, behind which a delivery waited (issue 1747). The queues the running ask did not come from are let go of and bound again after it.
37 lines
1.4 KiB
Go
37 lines
1.4 KiB
Go
package link
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/nats-io/nats.go"
|
|
)
|
|
|
|
// Issue 1747: a builder never holds a message it does not start. A message the server sends after a fetch gave up lands in that
|
|
// queue's subscription; while an ask runs, the queues it does not come from are let go of, so such a message is not held
|
|
// unheartbeated for the whole run, and the queues are bound again before the next fetch.
|
|
|
|
func TestARunningAskLetsGoOfTheQueuesItDidNotComeFrom(t *testing.T) {
|
|
m, builds, _, other, _ := aMachine()
|
|
// A delivery build reached the builds queue's subscription after its fetch gave up: it sits in the buffer.
|
|
builds.waiting = []*nats.Msg{buildAsk()}
|
|
took := m.subs[1] // the running ask came from the ready queue
|
|
|
|
m.quiesce(took)
|
|
|
|
if !took.bound || took.pull == nil {
|
|
t.Error("the queue the running ask came from was let go of; its acknowledgements need it")
|
|
}
|
|
for _, q := range []*takeQueue{m.subs[0], m.subs[2]} {
|
|
if q.bound || q.pull != nil || q.sub != nil {
|
|
t.Errorf("the %s queue is still held while an ask runs", q.kind)
|
|
}
|
|
}
|
|
// Nothing is fetched from a queue that was let go of: a message in it cannot be taken unheartbeated.
|
|
if msg, _, _ := m.next(t.Context()); msg != nil {
|
|
t.Fatalf("a message was taken from a queue that was let go of: %s", msg.Data)
|
|
}
|
|
if builds.fetches() != 0 || other.fetches() != 0 {
|
|
t.Errorf("fetched from a queue that was let go of: builds %d, other %d", builds.fetches(), other.fetches())
|
|
}
|
|
}
|