State a tool check that waits for the operator as waiting (issue 386, ADR 0283)
A module whose only fault was a secret the operator had not given yet was stated unhealthy, failed its first-node gate and was put back. The engine now reads the tool's answer through mesh-sdk go/health and states such a resource waiting, with what it waits for, on one look; a malformed wait stays unhealthy.
This commit is contained in:
+16
-15
@@ -9,6 +9,8 @@ import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/health"
|
||||
)
|
||||
|
||||
// Queue is the node-engine's one apply queue (novox/hq to-be 45 §6, ADR 0227 rule 1).
|
||||
@@ -531,21 +533,21 @@ func (q *Queue) timeout() time.Duration {
|
||||
// AskTool asks a module's tool on this machine's own node tools, as a declared health check (novox/hq ADR
|
||||
// 0240, to-be 48 §3), and reads its answer: healthy or not, with why. An error when there is no link open
|
||||
// or nothing answered — said as the check's failure, never as healthy.
|
||||
func (q *Queue) AskTool(ctx context.Context, module, tool string) (bool, string, error) {
|
||||
func (q *Queue) AskTool(ctx context.Context, module, tool string) (health.Answer, error) {
|
||||
q.init()
|
||||
q.mu.Lock()
|
||||
bus := q.bus
|
||||
q.mu.Unlock()
|
||||
if bus == nil {
|
||||
return false, "", errors.New("no link to the bus is open")
|
||||
return health.Answer{}, errors.New("no link to the bus is open")
|
||||
}
|
||||
asker, ok := bus.(ToolBus)
|
||||
if !ok {
|
||||
return false, "", errors.New("the link to the bus open now cannot ask a tool")
|
||||
return health.Answer{}, errors.New("the link to the bus open now cannot ask a tool")
|
||||
}
|
||||
reply, err := asker.Ask(ctx, ToolSubject(module, tool, q.Membership.Node), []byte("{}"))
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
return health.Answer{}, err
|
||||
}
|
||||
return ReadToolAnswer(reply)
|
||||
}
|
||||
@@ -572,24 +574,23 @@ func (q *Queue) AskController(ctx context.Context, body []byte) ([]byte, error)
|
||||
var ErrNotAsked = errors.New("not asked")
|
||||
|
||||
// ReadToolAnswer reads a tool's reply envelope — `{result, error}`, as the node tools answer every call —
|
||||
// as a health answer: an error is not healthy, and so is a result that does not say `healthy: true`.
|
||||
func ReadToolAnswer(reply []byte) (bool, string, error) {
|
||||
// as a health answer, through the SDK's reader (novox/hq ADR 0283): healthy, unhealthy, or waits for the
|
||||
// operator with what it waits for. An error, and a result that is not an answer, are unhealthy; a wait the
|
||||
// SDK cannot check is unhealthy too, so a malformed one never excuses anything.
|
||||
func ReadToolAnswer(reply []byte) (health.Answer, error) {
|
||||
var env struct {
|
||||
Result json.RawMessage `json:"result"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
if err := json.Unmarshal(reply, &env); err != nil {
|
||||
return false, "", fmt.Errorf("its answer is not one: %w", err)
|
||||
return health.Answer{}, fmt.Errorf("its answer is not one: %w", err)
|
||||
}
|
||||
if env.Error != "" {
|
||||
return false, env.Error, nil
|
||||
return health.Unhealthy(env.Error), nil
|
||||
}
|
||||
var a struct {
|
||||
Healthy bool `json:"healthy"`
|
||||
Why string `json:"why"`
|
||||
a, err := health.Read(env.Result)
|
||||
if err != nil {
|
||||
return health.Unhealthy("it answered something other than healthy or not"), nil
|
||||
}
|
||||
if err := json.Unmarshal(env.Result, &a); err != nil {
|
||||
return false, "it answered something other than healthy or not", nil
|
||||
}
|
||||
return a.Healthy, a.Why, nil
|
||||
return a, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user