Say a timeout is not a failure, and where the controller keeps the answer (hq issue 265)
This commit is contained in:
@@ -28,7 +28,9 @@ import (
|
|||||||
"github.com/novox/mesh-tools/node-tools/internal/wire"
|
"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 RequestTimeout = 30 * time.Second
|
||||||
|
|
||||||
const assignmentsStream = "ASSIGNMENTS"
|
const assignmentsStream = "ASSIGNMENTS"
|
||||||
|
|||||||
@@ -117,6 +117,9 @@ var (
|
|||||||
timedOut = regexp.MustCompile(`(?i)timeout`)
|
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.
|
// whyItFailed says why a call failed, so the remedy is in the words.
|
||||||
func whyItFailed(key string, err error) string {
|
func whyItFailed(key string, err error) string {
|
||||||
if err == nil {
|
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 " +
|
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."
|
"person's by `operator issue`, the console's by its manifest."
|
||||||
case timedOut.MatchString(msg):
|
case timedOut.MatchString(msg):
|
||||||
return key + " did not answer in time. Something is serving it, so this is the tool being slow " +
|
// **A timeout is not a failure** (novox/hq issue 265). Something took the call, so it may
|
||||||
"rather than absent."
|
// 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
|
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