Add comments
Yuri Shkuro
6 years ago
117 | 117 | // Endpoints yields the current set of (presumably identical) endpoints, ordered |
118 | 118 | // lexicographically by the corresponding instance string. |
119 | 119 | func (c *endpointCache) Endpoints() ([]endpoint.Endpoint, error) { |
120 | // in the steady state we're going to have many goroutines calling Endpoints() | |
121 | // concurrently, so to minimize contention we use a shared R-lock. | |
120 | 122 | c.mtx.RLock() |
121 | 123 | |
122 | 124 | if c.err == nil || c.timeNow().Before(c.invalidateDeadline) { |
125 | 127 | } |
126 | 128 | |
127 | 129 | c.mtx.RUnlock() |
130 | ||
131 | // in case of an error, switch to an exclusive lock. | |
128 | 132 | c.mtx.Lock() |
129 | 133 | defer c.mtx.Unlock() |
130 | 134 | |
131 | // Re-check due to a race between RUnlock() and Lock(). | |
135 | // re-check condition due to a race between RUnlock() and Lock(). | |
132 | 136 | if c.err == nil || c.timeNow().Before(c.invalidateDeadline) { |
133 | 137 | return c.endpoints, nil |
134 | 138 | } |