# HG changeset patch # User Chris Jones # Date 1378696576 -3600 # Node ID f35f853a52b6ce951ea8561d4cafaa6398ce8d82 # Parent a4755a42af1905472aab7642cab2b31336ba8463 Simplified and debugged the filter logic. diff -r a4755a42af19 -r f35f853a52b6 xmpp/filter.go --- a/xmpp/filter.go Mon Sep 09 02:13:07 2013 +0100 +++ b/xmpp/filter.go Mon Sep 09 04:16:16 2013 +0100 @@ -7,31 +7,21 @@ // the top of the stack. Receive stanzas at the bottom of the stack on // input. Send stanzas out the top of the stack on output. func filterMgr(filterAdd <-chan Filter, input <-chan Stanza, output chan<- Stanza) { - botFiltIn := output - topFiltOut := input - -loop: + defer close(output) for { select { case stan, ok := <-input: if !ok { - break loop - } - botFiltIn <- stan - - case stan, ok := <-topFiltOut: - if !ok { - break loop + return } output <- stan case filt := <-filterAdd: - newTop := make(chan Stanza) - go filt(topFiltOut, newTop) - topFiltOut = newTop + ch := make(chan Stanza) + go filt(input, ch) + input = ch } } - close(botFiltIn) } // AddRecvFilter adds a new filter to the top of the stack through which diff -r a4755a42af19 -r f35f853a52b6 xmpp/filter_test.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xmpp/filter_test.go Mon Sep 09 04:16:16 2013 +0100 @@ -0,0 +1,67 @@ +package xmpp + +import ( + "fmt" + "strconv" + "testing" +) + +func TestCloseIn(t *testing.T) { + add := make(chan Filter) + in := make(chan Stanza) + out := make(chan Stanza) + go filterMgr(add, in, out) + close(in) + _, ok := <-out + if ok { + fmt.Errorf("out didn't close") + } +} + +func passthru(in <-chan Stanza, out chan<- Stanza) { + defer close(out) + for stan := range in { + out <- stan + } +} + +func TestFilters(t *testing.T) { + for n := 0; n < 10; n++ { + filterN(n, t) + } +} + +func filterN(numFilts int, t *testing.T) { + add := make(chan Filter) + in := make(chan Stanza) + out := make(chan Stanza) + go filterMgr(add, in, out) + for i := 0; i < numFilts; i++ { + add <- passthru + } + go func() { + for i := 0; i < 100; i++ { + msg := Message{} + msg.Id = fmt.Sprintf("%d", i) + in <- &msg + } + }() + for i := 0; i < 100; i++ { + stan := <-out + msg, ok := stan.(*Message) + if !ok { + t.Errorf("N = %d: msg %d not a Message: %#v", numFilts, + i, stan) + continue + } + n, err := strconv.Atoi(msg.Header.Id) + if err != nil { + t.Errorf("N = %d: msg %d parsing ID '%s': %v", numFilts, + i, msg.Header.Id, err) + continue + } + if n != i { + t.Errorf("N = %d: msg %d wrong id %d", numFilts, i, n) + } + } +}