messenger: clear the state problem once a write succeeds again, so the status stops saying a failure that passed (issue 1507)

This commit is contained in:
2026-10-28 10:05:09 +01:00
parent 6cea12a023
commit e7abe3e3e4
2 changed files with 36 additions and 3 deletions
+16
View File
@@ -1130,6 +1130,8 @@ func (h *Holder) record(s Sent) {
if h.Store != nil {
if err := h.Store.PutRecent(recent); err != nil {
h.noteStore(err)
} else {
h.storeWritten()
}
}
}
@@ -1143,6 +1145,20 @@ func (h *Holder) persist(r *Record) {
h.mu.Unlock()
if err := h.Store.Put(c); err != nil {
h.noteStore(err)
} else {
h.storeWritten()
}
}
// storeWritten clears a state problem once a write succeeds again: the status says what holds now, never a
// failure that passed (issue 1507's reading of 2026-10-28: a verdict kept a single failure of the day before).
func (h *Holder) storeWritten() {
h.mu.Lock()
was := h.storeErr
h.storeErr = ""
h.mu.Unlock()
if was != "" {
h.Logf("[messenger] writes its state again (it could not: %s)", was)
}
}
+20 -3
View File
@@ -71,9 +71,14 @@ type memStore struct {
passes map[string]Pass
// puts counts the writes, so a write of bytes identical to what is stored is still seen (issue 422's review).
puts int
// fail, when set, refuses every write of a record or of the sends, as the bus does with no responders.
fail error
}
func (m *memStore) Put(r Record) error {
if m.fail != nil {
return m.fail
}
if m.recs == nil {
m.recs = map[string]Record{}
}
@@ -89,7 +94,13 @@ func (m *memStore) All() ([]Record, error) {
}
return out, nil
}
func (m *memStore) PutRecent(s []Sent) error { m.recent = s; return nil }
func (m *memStore) PutRecent(s []Sent) error {
if m.fail != nil {
return m.fail
}
m.recent = s
return nil
}
func (m *memStore) PutWalk(w Walk) error {
if m.walks == nil {
m.walks = map[string]Walk{}
@@ -431,15 +442,21 @@ func TestEscalationIsSaidOnce(t *testing.T) {
}
func TestAChannelThatCannotSendSaysSoAndIsTriedAgain(t *testing.T) {
h, tg, _, c, _ := newHolder(t)
h, tg, _, c, store := newHolder(t)
h.Desk = nil
tg.fail = errors.New("telegram sendMessage: cannot connect (dial)")
// The state could not be written either, once: said while it lasts, and no longer once a write succeeds
// (issue 1507's reading of 2026-10-28: a verdict kept a day-old "no responders").
store.fail = errors.New("nats: no responders available for request")
h.Condition(EventRaised, cond("machine.ace.silent", Urgent, "silent"))
st := h.Status("listening")
if !strings.HasPrefix(st.Verdict, "CANNOT SEND") || len(st.Unsent) != 1 || st.Channels[0].LastError == "" {
t.Fatalf("status: %+v", st)
}
tg.fail = nil
if st.StateProblem == "" {
t.Fatalf("a failed state write is not said: %+v", st)
}
tg.fail, store.fail = nil, nil
h.Flush()
if len(tg.sends) != 0 {
t.Fatalf("tried again before a minute")