package link import ( "testing" "time" "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()) } } // Once the ask is settled the queue it came from is let go of too: a second message the server delivered into its subscription // on a pull request still open is not run after the ask ends (review of 1747). func TestTheQueueTheAskCameFromIsLetGoOfWhenTheAskEnds(t *testing.T) { m, _, ready, _, _ := aMachine() ready.waiting = []*nats.Msg{askedAgo(time.Minute, 2, true)} m.quiesce(nil) for _, q := range m.subs { if q.bound || q.pull != nil { t.Errorf("the %s queue is still held after the ask ended", q.kind) } } m.subs[0].bound, m.subs[0].pull = true, &fakeQueue{} if msg, _, _ := m.next(t.Context()); msg != nil || ready.fetches() != 0 { t.Fatal("a message held in the kept queue's subscription was taken after the ask ended") } }