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