Merge pull request 'Say a timeout is not a failure, and where the controller keeps the answer (hq issue 265)' (#15) from fix/a-timeout-is-not-a-failure into main
mesh/delivery held for a person: merged without a passing check: only a person decides that it goes on
mesh/delivery held for a person: merged without a passing check: only a person decides that it goes on
This commit was merged in pull request #15.
This commit is contained in:
@@ -28,7 +28,9 @@ import (
|
||||
"github.com/novox/mesh-tools/node-tools/internal/wire"
|
||||
)
|
||||
|
||||
// RequestTimeout is how long a call waits for its answer — what modules already expect.
|
||||
// RequestTimeout is how long a call waits for its answer — what modules already expect. The
|
||||
// controller answers its verbs well inside it (its AnswerWithin, ten seconds), with a call id while a
|
||||
// verb still runs, so a caller is never left guessing past this (novox/hq issue 265).
|
||||
const RequestTimeout = 30 * time.Second
|
||||
|
||||
const assignmentsStream = "ASSIGNMENTS"
|
||||
|
||||
@@ -117,6 +117,9 @@ var (
|
||||
timedOut = regexp.MustCompile(`(?i)timeout`)
|
||||
)
|
||||
|
||||
// controllerSeat is the seat whose holder keeps what came of every call (novox/hq issue 265).
|
||||
const controllerSeat = "mesh-controller"
|
||||
|
||||
// whyItFailed says why a call failed, so the remedy is in the words.
|
||||
func whyItFailed(key string, err error) string {
|
||||
if err == nil {
|
||||
@@ -135,8 +138,18 @@ func whyItFailed(key string, err error) string {
|
||||
return "this account may not call " + key + ". What it may call was fixed when it was issued — a " +
|
||||
"person's by `operator issue`, the console's by its manifest."
|
||||
case timedOut.MatchString(msg):
|
||||
return key + " did not answer in time. Something is serving it, so this is the tool being slow " +
|
||||
"rather than absent."
|
||||
// **A timeout is not a failure** (novox/hq issue 265). Something took the call, so it may
|
||||
// still be running and may already have done what was asked: a push said this while it pushed.
|
||||
said := key + " did not answer within " + bus.RequestTimeout.String() + ". That is not a failure: " +
|
||||
"something is serving it, so it may still be running and may already have done what was " +
|
||||
"asked — check before repeating a call that changes the mesh."
|
||||
if strings.HasPrefix(strings.TrimPrefix(key, "seat:"), controllerSeat+".") {
|
||||
// The controller answers every call within seconds, with an id while it runs, so silence
|
||||
// from it is an answer lost on the way — which it keeps.
|
||||
said += " The controller answers every call within seconds, so its answer was lost on the " +
|
||||
"way; " + controllerSeat + ".calls lists its recent calls and what came of each."
|
||||
}
|
||||
return said
|
||||
}
|
||||
return key + " failed: " + msg
|
||||
}
|
||||
|
||||
@@ -20,3 +20,18 @@ func TestARefusalIsSaidOnlyForTheBussOwn(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// **A timeout says it is not a failure** (novox/hq issue 265): a push that outlasted the wait had
|
||||
// pushed, and the caller read "did not answer in time". And from the controller, where its answer is.
|
||||
func TestATimeoutIsNotAFailure(t *testing.T) {
|
||||
got := whyItFailed("seat:mesh-controller.push", errors.New("timeout"))
|
||||
for _, want := range []string{"not a failure", "may already have done", "mesh-controller.calls"} {
|
||||
if !strings.Contains(got, want) {
|
||||
t.Errorf("a controller timeout does not say %q: %s", want, got)
|
||||
}
|
||||
}
|
||||
if other := whyItFailed("novox/postgres.postgres_list_databases", errors.New("timeout")); !strings.Contains(other, "not a failure") ||
|
||||
strings.Contains(other, "calls") {
|
||||
t.Errorf("a module's timeout: %s", other)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user