Set.Each, also builtin Channel broadcast goroutine

This commit is contained in:
Andrey Petrov 2014-12-22 21:47:07 -08:00
parent 7beb7f99bb
commit a1d5cc6735
4 changed files with 31 additions and 26 deletions

View File

@ -3,6 +3,7 @@ package chat
import "fmt"
const historyLen = 20
const channelBuffer = 10
// Channel definition, also a Set of User Items
type Channel struct {
@ -10,19 +11,35 @@ type Channel struct {
topic string
history *History
users *Set
broadcast chan<- Message
broadcast chan Message
}
func NewChannel(id string, broadcast chan<- Message) *Channel {
// Create new channel and start broadcasting goroutine.
func NewChannel(id string) *Channel {
broadcast := make(chan Message, channelBuffer)
ch := Channel{
id: id,
broadcast: broadcast,
history: NewHistory(historyLen),
users: NewSet(),
}
go func() {
for m := range broadcast {
ch.users.Each(func(u Item) {
u.(*User).Send(m)
})
}
}()
return &ch
}
func (ch *Channel) Close() {
close(ch.broadcast)
}
func (ch *Channel) Send(m Message) {
ch.broadcast <- m
}

View File

@ -8,20 +8,12 @@ import (
func TestChannel(t *testing.T) {
var expected, actual []byte
out := make(chan Message)
defer close(out)
s := &MockScreen{}
u := NewUser("foo")
go func() {
for msg := range out {
t.Logf("Broadcasted: ", msg.String())
u.Send(msg)
}
}()
ch := NewChannel("")
defer ch.Close()
ch := NewChannel("", out)
err := ch.Join(u)
if err != nil {
t.Error(err)

View File

@ -24,18 +24,5 @@ func (h *Host) broadcast(ch *Channel, m Message) {
}
func (h *Host) CreateChannel(id string) *Channel {
out := make(chan Message, 20)
ch := NewChannel(id, out)
go func() {
for msg := range out {
if msg.IsCommand() {
go h.handleCommand(msg)
continue
}
h.broadcast(ch, msg)
}
}()
return ch
return NewChannel(id)
}

View File

@ -87,6 +87,15 @@ func (s *Set) Remove(item Item) error {
return nil
}
// Loop over every item while holding a read lock and apply fn
func (s *Set) Each(fn func(item Item)) {
s.RLock()
for _, item := range s.lookup {
fn(item)
}
s.RUnlock()
}
// List users by prefix, case insensitive
func (s *Set) ListPrefix(prefix string) []Item {
r := []Item{}