github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/libkb/identify_dispatch.go (about) 1 package libkb 2 3 import ( 4 "sync" 5 6 keybase1 "github.com/keybase/client/go/protocol/keybase1" 7 ) 8 9 type IdentifyDispatchMsg struct { 10 Target keybase1.UID 11 } 12 13 type IdentifyDispatch struct { 14 sync.Mutex 15 listeners []chan<- IdentifyDispatchMsg 16 } 17 18 func 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. 25 func (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. 39 func (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. 62 func (d *IdentifyDispatch) OnLogout() { 63 d.Lock() 64 defer d.Unlock() 65 d.listeners = nil 66 }