mirror of https://github.com/docker/docs.git
54 lines
1.2 KiB
Go
54 lines
1.2 KiB
Go
package utils
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/docker/beam"
|
|
"github.com/docker/beam/inmem"
|
|
"sync"
|
|
)
|
|
|
|
// Hub passes messages to dynamically registered handlers.
|
|
type Hub struct {
|
|
handlers *StackSender
|
|
tasks sync.WaitGroup
|
|
}
|
|
|
|
func NewHub() *Hub {
|
|
return &Hub{
|
|
handlers: NewStackSender(),
|
|
}
|
|
}
|
|
|
|
func (hub *Hub) Send(msg *beam.Message, mode int) (beam.Receiver, beam.Sender, error) {
|
|
if msg.Name == "register" {
|
|
if mode&beam.R == 0 {
|
|
return nil, nil, fmt.Errorf("register: no return channel")
|
|
}
|
|
fmt.Printf("[hub] received %v\n", msg)
|
|
hYoutr, hYoutw := inmem.Pipe()
|
|
hYinr, hYinw := inmem.Pipe()
|
|
// Register the new handler on top of the others,
|
|
// and get a reference to the previous stack of handlers.
|
|
prevHandlers := hub.handlers.Add(hYinw)
|
|
// Pass requests from the new handler to the previous chain of handlers
|
|
// hYout -> hXin
|
|
hub.tasks.Add(1)
|
|
go func() {
|
|
defer hub.tasks.Done()
|
|
Copy(prevHandlers, hYoutr)
|
|
hYoutr.Close()
|
|
}()
|
|
return hYinr, hYoutw, nil
|
|
}
|
|
fmt.Printf("sending %#v to %d handlers\n", msg, hub.handlers.Len())
|
|
return hub.handlers.Send(msg, mode)
|
|
}
|
|
|
|
func (hub *Hub) Wait() {
|
|
hub.tasks.Wait()
|
|
}
|
|
|
|
func (hub *Hub) Close() error {
|
|
return hub.handlers.Close()
|
|
}
|