An event a module's consumer heard after the module was dropped for a reload read a deleted entry and panicked node-tools, taking every tool on the machine down. The handler now refuses an event of a consumer that is no longer the module's, and a stopped hearing hands nothing on and offers the event again at once. A bundle that writes beside itself (a cache, a socket) loaded itself again after every quiet spell, because the signature took in every file in its directory. A delivery puts every file in place anew, so the entrypoint alone tells a new build. The watch also looks once as it begins, so a bundle that came between its load and the watch is not missed. Tests: 1945/AC23 and AC24 in internal/runtime/reload_test.go, and a stopped hearing in internal/bus/hearing_stopped_test.go.
49 lines
1.7 KiB
Go
49 lines
1.7 KiB
Go
package bus
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/nats-io/nats.go"
|
|
"github.com/nats-io/nats.go/jetstream"
|
|
)
|
|
|
|
// heardMsg is a delivered event as a consumer's loop hands it, saying how it was settled.
|
|
type heardMsg struct {
|
|
jetstream.Msg
|
|
mu sync.Mutex
|
|
settled []string
|
|
}
|
|
|
|
func (m *heardMsg) Subject() string { return "mesh.mod.alpha.event.happened" }
|
|
func (m *heardMsg) Headers() nats.Header { return nats.Header{} }
|
|
func (m *heardMsg) Data() []byte { return []byte(`{"n":1}`) }
|
|
func (m *heardMsg) InProgress() error { return nil }
|
|
func (m *heardMsg) Ack() error { return m.say("ack") }
|
|
func (m *heardMsg) Nak() error { return m.say("nak") }
|
|
func (m *heardMsg) NakWithDelay(time.Duration) error { return m.say("nak-delayed") }
|
|
func (m *heardMsg) Term() error { return m.say("term") }
|
|
func (m *heardMsg) say(how string) error {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
m.settled = append(m.settled, how)
|
|
return nil
|
|
}
|
|
|
|
// An event the bus hands a hearing after it was stopped (a module's bundle loaded again, issue 1945) is
|
|
// offered again at once and never handed to the module: the module's handler that heard it may be gone.
|
|
func TestAHearingStoppedHandsNoEventOnAndOffersItAgain(t *testing.T) {
|
|
delivered := 0
|
|
h := newHearing(nil, nil, "alpha", func(Envelope) error { delivered++; return nil })
|
|
h.stop()
|
|
msg := &heardMsg{}
|
|
h.handle(msg)
|
|
if delivered != 0 {
|
|
t.Errorf("a stopped hearing handed the event to the module")
|
|
}
|
|
if len(msg.settled) != 1 || msg.settled[0] != "nak" {
|
|
t.Errorf("a stopped hearing settled the event as %v, want it offered again at once (nak)", msg.settled)
|
|
}
|
|
}
|