vail/cmd/vail/book.go

101 lines
1.8 KiB
Go
Raw Normal View History

2020-04-12 20:40:52 -06:00
package main
import (
"log"
)
2022-05-15 17:38:57 -06:00
// Book maps names to repeaters
//
// It ensures that names map 1-1 to repeaters.
2020-04-12 20:40:52 -06:00
type Book struct {
2022-05-15 17:38:57 -06:00
entries map[string]*Repeater
events chan bookEvent
makeRepeater func() *Repeater
2020-04-12 20:40:52 -06:00
}
func NewBook() Book {
return Book{
2022-05-15 17:38:57 -06:00
entries: make(map[string]*Repeater),
events: make(chan bookEvent, 5),
makeRepeater: NewRepeater,
2020-04-12 20:40:52 -06:00
}
}
type bookEventType int
2020-05-30 22:23:53 -06:00
2020-04-12 20:40:52 -06:00
const (
joinEvent = bookEventType(iota)
partEvent
sendEvent
)
type bookEvent struct {
eventType bookEventType
2020-05-30 22:23:53 -06:00
name string
2022-05-15 21:12:36 -06:00
sender MessageSender
2022-05-15 15:57:12 -06:00
m Message
2020-04-12 20:40:52 -06:00
}
2022-05-15 17:38:57 -06:00
// Join adds a writer to a named repeater
2022-05-15 21:12:36 -06:00
func (b Book) Join(name string, sender MessageSender) {
2020-04-12 20:40:52 -06:00
b.events <- bookEvent{
eventType: joinEvent,
2020-05-30 22:23:53 -06:00
name: name,
2022-05-15 21:12:36 -06:00
sender: sender,
2020-04-12 20:40:52 -06:00
}
}
2022-05-15 17:38:57 -06:00
// Part removes a writer from a named repeater
2022-05-15 21:12:36 -06:00
func (b Book) Part(name string, sender MessageSender) {
2020-04-12 20:40:52 -06:00
b.events <- bookEvent{
eventType: partEvent,
2020-05-30 22:23:53 -06:00
name: name,
2022-05-15 21:12:36 -06:00
sender: sender,
2020-04-12 20:40:52 -06:00
}
}
2022-05-15 17:38:57 -06:00
// Send transmits a message to the named repeater
2022-05-15 15:57:12 -06:00
func (b Book) Send(name string, m Message) {
2020-04-12 20:40:52 -06:00
b.events <- bookEvent{
eventType: sendEvent,
2020-05-30 22:23:53 -06:00
name: name,
2022-05-15 15:57:12 -06:00
m: m,
2020-04-12 20:40:52 -06:00
}
}
2022-05-15 17:38:57 -06:00
// Run is the endless run loop
2020-04-12 20:40:52 -06:00
func (b Book) Run() {
for {
b.loop()
}
}
func (b Book) loop() {
event := <-b.events
repeater, ok := b.entries[event.name]
switch event.eventType {
case joinEvent:
2020-05-30 22:23:53 -06:00
if !ok {
2022-05-15 17:38:57 -06:00
repeater = b.makeRepeater()
2020-04-12 20:40:52 -06:00
b.entries[event.name] = repeater
}
2022-05-15 21:12:36 -06:00
repeater.Join(event.sender)
2020-04-12 20:40:52 -06:00
case partEvent:
2020-05-30 22:23:53 -06:00
if !ok {
2020-04-12 20:40:52 -06:00
log.Println("WARN: Parting an empty channel:", event.name)
break
}
2022-05-15 21:12:36 -06:00
repeater.Part(event.sender)
2020-04-12 20:46:51 -06:00
if repeater.Listeners() == 0 {
2020-04-12 20:40:52 -06:00
delete(b.entries, event.name)
}
case sendEvent:
2020-05-30 22:23:53 -06:00
if !ok {
2020-04-12 20:40:52 -06:00
log.Println("WARN: Sending to an empty channel:", event.name)
break
}
2022-05-15 15:57:12 -06:00
repeater.Send(event.m)
2020-04-12 20:40:52 -06:00
}
}