Closed
Description
Exhibit 1:
func (i *Ingester) query(ctx context.Context, from, through model.Time, matchers []*labels.Matcher) (model.Matrix, error) {
i.queries.Inc()
i.userStatesMtx.RLock()
defer i.userStatesMtx.RUnlock()
state, err := i.userStates.getOrCreate(ctx)
In what sense is this a Read lock if we can Create a user state inside it?
And why do we hold this lock (over all user states) for the duration of the query over one?
There are five other RLock
calls which are very similar.
Exhibit 2:
// TransferChunks receives all the chunks from another ingester.
func (i *Ingester) TransferChunks(stream client.Ingester_TransferChunksServer) error {
[...]
i.userStatesMtx.Lock()
defer i.userStatesMtx.Unlock()
if err := i.ChangeState(ring.ACTIVE); err != nil {
return err
}
i.userStates = userStates
return nil
This is the only place a write-lock is taken on userStatesMtx
, and only for as long as it takes to CAS the state change.
Since there is a lock mtx
inside userStates
protecting its data, I suspect that userStatesMtx
is left-over from some earlier implementation that needed it.