@@ -148,8 +148,7 @@ func (sd *StoreDetailMu) status(
148
148
nl NodeLivenessFunc ,
149
149
suspectDuration time.Duration ,
150
150
) storeStatus {
151
- sd .Lock ()
152
- defer sd .Unlock ()
151
+ sd .RLock () // all exist paths will RUnlock() the lock.
153
152
// During normal operation, we expect the state transitions for stores to look like the following:
154
153
//
155
154
// +-----------------------+
@@ -171,19 +170,37 @@ func (sd *StoreDetailMu) status(
171
170
// heartbeat
172
171
//
173
172
173
+ // updateLastUnavailableAndReturnStatusRLocked upgrades the read lock to a
174
+ // write lock, updates the LastUnavailable timestamp, returns the store
175
+ // status, and unlocks the write lock.
176
+ updateLastUnavailableAndReturnStatusRLocked := func (
177
+ lastUnavailable hlc.Timestamp , returnStatus storeStatus ,
178
+ ) storeStatus {
179
+ sd .RUnlock ()
180
+ sd .Lock ()
181
+ defer sd .Unlock ()
182
+ sd .LastUnavailable = lastUnavailable
183
+ return returnStatus
184
+ }
185
+
186
+ // returnStatusRLocked unlocks the read lock and returns the store status.
187
+ returnStatusRLocked := func (returnStatus storeStatus ) storeStatus {
188
+ defer sd .RUnlock ()
189
+ return returnStatus
190
+ }
191
+
174
192
// The store is considered dead if it hasn't been updated via gossip
175
193
// within the liveness threshold. Note that LastUpdatedTime is set
176
194
// when the store detail is created and will have a non-zero value
177
195
// even before the first gossip arrives for a store.
178
196
deadAsOf := sd .LastUpdatedTime .AddDuration (deadThreshold )
179
197
if now .After (deadAsOf ) {
180
- sd .LastUnavailable = now
181
- return storeStatusDead
198
+ return updateLastUnavailableAndReturnStatusRLocked (now , storeStatusDead )
182
199
}
183
200
// If there's no descriptor (meaning no gossip ever arrived for this
184
201
// store), return unavailable.
185
202
if sd .Desc == nil {
186
- return storeStatusUnknown
203
+ return returnStatusRLocked ( storeStatusUnknown )
187
204
}
188
205
189
206
// Even if the store has been updated via gossip, we still rely on
@@ -193,34 +210,31 @@ func (sd *StoreDetailMu) status(
193
210
// dead -> decommissioning -> unknown -> draining -> suspect -> available.
194
211
switch nl (sd .Desc .Node .NodeID ) {
195
212
case livenesspb .NodeLivenessStatus_DEAD , livenesspb .NodeLivenessStatus_DECOMMISSIONED :
196
- sd .LastUnavailable = now
197
- return storeStatusDead
213
+ return updateLastUnavailableAndReturnStatusRLocked (now , storeStatusDead )
198
214
case livenesspb .NodeLivenessStatus_DECOMMISSIONING :
199
- return storeStatusDecommissioning
215
+ return returnStatusRLocked ( storeStatusDecommissioning )
200
216
case livenesspb .NodeLivenessStatus_UNAVAILABLE :
201
- sd .LastUnavailable = now
202
- return storeStatusUnknown
217
+ return updateLastUnavailableAndReturnStatusRLocked (now , storeStatusUnknown )
203
218
case livenesspb .NodeLivenessStatus_UNKNOWN :
204
- return storeStatusUnknown
219
+ return returnStatusRLocked ( storeStatusUnknown )
205
220
case livenesspb .NodeLivenessStatus_DRAINING :
206
- sd .LastUnavailable = now
207
- return storeStatusDraining
221
+ return updateLastUnavailableAndReturnStatusRLocked (now , storeStatusDraining )
208
222
}
209
223
210
224
// A store is throttled if it has missed receiving snapshots recently.
211
225
if sd .ThrottledUntil .After (now ) {
212
- return storeStatusThrottled
226
+ return returnStatusRLocked ( storeStatusThrottled )
213
227
}
214
228
215
229
// Check whether the store is currently suspect. We measure that by
216
230
// looking at the time it was last unavailable making sure we have not seen any
217
231
// failures for a period of time defined by StoreSuspectDuration.
218
232
if sd .LastUnavailable .AddDuration (suspectDuration ).After (now ) {
219
- return storeStatusSuspect
233
+ return returnStatusRLocked ( storeStatusSuspect )
220
234
}
221
235
222
236
// Clear out the LastUnavailable once we return available status.
223
- return storeStatusAvailable
237
+ return returnStatusRLocked ( storeStatusAvailable )
224
238
}
225
239
226
240
// localityWithString maintains a string representation of each locality along
0 commit comments