package hub import ( "blicky.net/tanja" ) type Manager struct { ses *tanja.Session node *tanja.Node closed chan bool hubs map[string]*hub } func New(node *tanja.Node) *Manager { s := &Manager{} s.ses = node.Session() s.closed = make(chan bool) s.hubs = make(map[string]*hub) s.node = node s.ses.Register(true, "hub", nil, "new").Callback(func(t *tanja.Message) { s.tNew(t) }) s.ses.Register(false, "hub", nil, "close").Callback(func(t *tanja.Message) { s.tClose(t) }) return s } func (s *Manager) tNew(m *tanja.Message) { n := m.Tup[1].String() if s.hubs[n] != nil { m.Reply(0) } else if n != "" { s.hubs[n] = newHub(s.node, n) m.Reply(1) } m.Close() } func (s *Manager) tClose(m *tanja.Message) { if m.Tup[1].WC() { // Close all for _, h := range s.hubs { go h.close() } s.hubs = make(map[string]*hub) } else { // Close one n := m.Tup[1].String() if h := s.hubs[n]; h != nil { delete(s.hubs, n) go h.close() } } } func (s *Manager) Run() { s.ses.Run() // Close all hubs (in parallel) ch := make(chan bool, 10) for _, h := range s.hubs { go func() { h.close() ch <- true }() } for i := len(s.hubs); i > 0; i-- { <-ch } close(s.closed) } func (s *Manager) Close() { s.ses.Close() <-s.closed }