1package libkb 2 3import ( 4 "sync" 5 6 keybase1 "github.com/keybase/client/go/protocol/keybase1" 7) 8 9type IdentifyDispatchMsg struct { 10 Target keybase1.UID 11} 12 13type IdentifyDispatch struct { 14 sync.Mutex 15 listeners []chan<- IdentifyDispatchMsg 16} 17 18func NewIdentifyDispatch() *IdentifyDispatch { return &IdentifyDispatch{} } 19 20// NotifyTrackingSuccess notifies listeners that a target user has been found to satisfy tracking. 21// This could be through 22// - An identify call that heeded the active user's tracking of the target. 23// - A user tracked or untracked the target. 24// When the active user is the target all bets are off. 25func (d *IdentifyDispatch) NotifyTrackingSuccess(mctx MetaContext, target keybase1.UID) { 26 mctx.Debug("IdentifyDispatch.NotifyTrackingSuccess(%v)", target) 27 d.Lock() 28 defer d.Unlock() 29 for _, listener := range d.listeners { 30 select { 31 case listener <- IdentifyDispatchMsg{Target: target}: 32 default: 33 } 34 } 35} 36 37// Subscribe to notifications. 38// `unsubscribe` releases resources associated with the subscription and should be called asap. 39func (d *IdentifyDispatch) Subscribe(mctx MetaContext) (unsubscribe func(), recvCh <-chan IdentifyDispatchMsg) { 40 mctx.Debug("IdentifyDispatch.Subscribe") 41 ch := make(chan IdentifyDispatchMsg, 10) 42 d.Lock() 43 defer d.Unlock() 44 d.listeners = append(d.listeners, ch) 45 unsubscribe = func() { 46 mctx.Debug("IdentifyDispatch.Unsubcribe") 47 d.Lock() 48 defer d.Unlock() 49 var listeners []chan<- IdentifyDispatchMsg 50 for _, ch2 := range d.listeners { 51 if ch == ch2 { 52 continue 53 } 54 listeners = append(listeners, ch2) 55 } 56 d.listeners = listeners 57 } 58 return unsubscribe, ch 59} 60 61// OnLogout drops all subscriptions. 62func (d *IdentifyDispatch) OnLogout() { 63 d.Lock() 64 defer d.Unlock() 65 d.listeners = nil 66} 67