123 lines
2.7 KiB
Go
123 lines
2.7 KiB
Go
package listeners
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"sync"
|
|
|
|
"log/slog"
|
|
)
|
|
|
|
// Config contains configuration values for a listener.
|
|
type Config struct {
|
|
// TLSConfig is a tls.Config configuration to be used with the listener.
|
|
// See examples folder for basic and mutual-tls use.
|
|
TLSConfig *tls.Config
|
|
}
|
|
|
|
// Listener is an interface for network listeners. A network listener listens
|
|
// for incoming client connections and adds them to the server.
|
|
type Listener interface {
|
|
Init(*slog.Logger) error // open the network address
|
|
Serve() // starting actively listening for new connections
|
|
ID() string // return the id of the listener
|
|
Address() string // the address of the listener
|
|
Protocol() string // the protocol in use by the listener
|
|
Close() // stop and close the listener
|
|
}
|
|
|
|
// Listeners contains the network listeners for the broker.
|
|
type Listeners struct {
|
|
ClientsWg sync.WaitGroup // a waitgroup that waits for all clients in all listeners to finish.
|
|
internal map[string]Listener // a map of active listeners.
|
|
sync.RWMutex
|
|
}
|
|
|
|
// New returns a new instance of Listeners.
|
|
func New() *Listeners {
|
|
return &Listeners{
|
|
internal: map[string]Listener{},
|
|
}
|
|
}
|
|
|
|
// Add adds a new listener to the listeners map, keyed on id.
|
|
func (l *Listeners) Add(val Listener) {
|
|
l.Lock()
|
|
defer l.Unlock()
|
|
l.internal[val.ID()] = val
|
|
}
|
|
|
|
// Get returns the value of a listener if it exists.
|
|
func (l *Listeners) Get(id string) (Listener, bool) {
|
|
l.RLock()
|
|
defer l.RUnlock()
|
|
val, ok := l.internal[id]
|
|
return val, ok
|
|
}
|
|
|
|
// Len returns the length of the listeners map.
|
|
func (l *Listeners) Len() int {
|
|
l.RLock()
|
|
defer l.RUnlock()
|
|
return len(l.internal)
|
|
}
|
|
|
|
// Delete removes a listener from the internal map.
|
|
func (l *Listeners) Delete(id string) {
|
|
l.Lock()
|
|
defer l.Unlock()
|
|
delete(l.internal, id)
|
|
}
|
|
|
|
// Serve starts a listener serving from the internal map.
|
|
func (l *Listeners) Serve(id string) {
|
|
l.RLock()
|
|
defer l.RUnlock()
|
|
listener := l.internal[id]
|
|
|
|
go func() {
|
|
listener.Serve()
|
|
}()
|
|
}
|
|
|
|
// ServeAll starts all listeners serving from the internal map.
|
|
func (l *Listeners) ServeAll() {
|
|
l.RLock()
|
|
i := 0
|
|
ids := make([]string, len(l.internal))
|
|
for id := range l.internal {
|
|
ids[i] = id
|
|
i++
|
|
}
|
|
l.RUnlock()
|
|
|
|
for _, id := range ids {
|
|
l.Serve(id)
|
|
}
|
|
}
|
|
|
|
// Close stops a listener from the internal map.
|
|
func (l *Listeners) Close(id string) {
|
|
l.RLock()
|
|
defer l.RUnlock()
|
|
if listener, ok := l.internal[id]; ok {
|
|
listener.Close()
|
|
}
|
|
}
|
|
|
|
// CloseAll iterates and closes all registered listeners.
|
|
func (l *Listeners) CloseAll() {
|
|
l.RLock()
|
|
i := 0
|
|
ids := make([]string, len(l.internal))
|
|
for id := range l.internal {
|
|
ids[i] = id
|
|
i++
|
|
}
|
|
l.RUnlock()
|
|
|
|
for _, id := range ids {
|
|
l.Close(id)
|
|
}
|
|
l.ClientsWg.Wait()
|
|
}
|