Asking a tool goes through the seam, and loses two problems
Step 3.4. On the new bus there is no reply queue to declare and no correlation to check: each account is granted one inbox prefix and no other, so an answer cannot reach the wrong asker. That settles a cost build.go records having paid — on a shared reply exchange every asker saw every result, which is why the correlation was checked rather than assumed. And a tool nobody serves says so at once rather than after the whole wait. The difference between "that module is down" and "that tool is slow" is the first thing a person asking wants, and both tests are against a real server because both are claims about what the server does, not about this code. RequestBuild stays as it is, and is a different shape on the new bus rather than the same one: a build takes minutes, so it is work submitted to a queue with the outcome returning to a reply subject the request carries — the pattern design 25 §2 already sets for anything crossing a stream. It touches the builder too, so it goes with that conversion.
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -93,3 +94,61 @@ func TestAnEventsSubjectIsDerivedFromItsSource(t *testing.T) {
|
||||
t.Fatal("two modules share an event subject, so neither owns its own name")
|
||||
}
|
||||
}
|
||||
|
||||
// A tool nobody serves says so at once. The difference between "that module is down" and "that
|
||||
// tool is slow" is the first thing a person asking wants, and waiting out the timeout to say it
|
||||
// is how a fast answer becomes a slow non-answer.
|
||||
func TestAskingAToolNobodyServesFailsAtOnce(t *testing.T) {
|
||||
url := os.Getenv("MESH_TEST_NATS")
|
||||
if url == "" {
|
||||
t.Skip("MESH_TEST_NATS unset")
|
||||
}
|
||||
conn, err := nats.Connect(url)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
bus := OverNATS{Conn: conn}
|
||||
began := time.Now()
|
||||
_, err = bus.AskTool(context.Background(), "nobody", "home", nil, 30*time.Second)
|
||||
if err == nil {
|
||||
t.Fatal("asking a tool nothing serves succeeded")
|
||||
}
|
||||
if took := time.Since(began); took > 2*time.Second {
|
||||
t.Errorf("took %v to say nothing serves it; the caller waited out the timeout", took)
|
||||
}
|
||||
if !strings.Contains(err.Error(), "nothing serves") {
|
||||
t.Errorf("the refusal does not say nobody is there: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// And a served tool answers, with no reply queue to declare and no correlation to check.
|
||||
func TestAskingAServedToolAnswers(t *testing.T) {
|
||||
url := os.Getenv("MESH_TEST_NATS")
|
||||
if url == "" {
|
||||
t.Skip("MESH_TEST_NATS unset")
|
||||
}
|
||||
conn, err := nats.Connect(url)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
sub, err := conn.Subscribe(ToolSubject("shop", "price"), func(m *nats.Msg) {
|
||||
_ = m.Respond([]byte(`{"total":12}`))
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
got, err := OverNATS{Conn: conn}.AskTool(context.Background(), "shop", "price",
|
||||
[]byte(`{"qty":4}`), 5*time.Second)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(got) != `{"total":12}` {
|
||||
t.Fatalf("the answer came back as %s", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user