MCPcopy Index your code
hub / github.com/coder/coder / updateLoop

Method updateLoop

tailnet/node.go:44–85  ·  view source on GitHub ↗

updateLoop waits until the config is dirty and then calls the callback with the newest node. It is intended only to be called internally, and shuts down when close() is called.

()

Source from the content-addressed store, hash-verified

42// updateLoop waits until the config is dirty and then calls the callback with the newest node.
43// It is intended only to be called internally, and shuts down when close() is called.
44func (u *nodeUpdater) updateLoop() {
45 u.L.Lock()
46 defer u.L.Unlock()
47 defer func() {
48 u.phase = closed
49 u.Broadcast()
50 }()
51 for {
52 for !(u.closing || u.dirty) {
53 u.phase = idle
54 u.Wait()
55 }
56 if u.closing {
57 u.logger.Debug(context.Background(), "closing nodeUpdater updateLoop")
58 return
59 }
60 u.dirty = false
61 u.phase = configuring
62 u.Broadcast()
63
64 callback := u.callback
65 if callback == nil {
66 u.logger.Debug(context.Background(), "skipped sending node; no node callback")
67 continue
68 }
69
70 // We cannot reach nodes without DERP for discovery. Therefore, there is no point in sending
71 // the node without this, and we can save ourselves from churn in the tailscale/wireguard
72 // layer.
73 node := u.nodeLocked()
74 if node.PreferredDERP == 0 {
75 u.logger.Debug(context.Background(), "skipped sending node; no PreferredDERP", slog.F("node", node))
76 continue
77 }
78
79 u.L.Unlock()
80 u.logger.Debug(context.Background(), "calling nodeUpdater callback", slog.F("node", node))
81 callback(node)
82 u.L.Lock()
83 u.sentNode = true
84 }
85}
86
87// close closes the nodeUpdate and stops it calling the node callback
88func (u *nodeUpdater) close() {

Callers 1

newNodeUpdaterFunction · 0.95

Calls 4

nodeLockedMethod · 0.95
WaitMethod · 0.65
LockMethod · 0.45
UnlockMethod · 0.45

Tested by

no test coverage detected