@@ -218,8 +218,10 @@ func Lock(ctx context.Context, queries ...[]Subquery) (results []Result, unlocke
218218
219219 roots := make ([][]int , len (queries ))
220220 cachesPresent := make (map [resource ]struct {}, resourceCount )
221+ // if there are no consistent locks, we don't add the root lock
222+ hasConsistentLocks := false
221223 // phase 1, requires no locks, check errors, dedupe, and build trees
222- if err = assembleQueries (queries , roots , cachesPresent ); err != nil {
224+ if hasConsistentLocks , err = assembleQueries (queries , roots , cachesPresent ); err != nil {
223225 return nil , func () {}, err
224226 }
225227
@@ -229,30 +231,34 @@ func Lock(ctx context.Context, queries ...[]Subquery) (results []Result, unlocke
229231 }
230232
231233 // phase 3, takes per-resource locks
232- merged := mergeQueries (queries )
234+ merged := mergeQueries (queries , hasConsistentLocks )
233235 results , unlocker , err = lockQuery (merged , len (queries ))
234236 if err == nil && ctx .Err () != nil {
235237 err = ctx .Err ()
236238 }
237239 return results , unlocker , err
238240}
239241
240- func assembleQueries (queries [][]Subquery , roots [][]int , cachesPresent map [resource ]struct {}) error {
242+ func assembleQueries (queries [][]Subquery , roots [][]int , cachesPresent map [resource ]struct {}) (bool , error ) {
243+ hasConsistentLocks := false
241244 for i , q := range queries {
242245 if err := checkError (q ); err != nil {
243- return err
246+ return false , err
244247 }
245248 ri , err := dedupe (q )
246249 if err != nil {
247- return err
250+ return false , err
248251 }
249252 for _ , sq := range q {
250253 cachesPresent [sq .res ] = struct {}{}
254+ if sq .op != list && sq .op != inconsistentRead {
255+ hasConsistentLocks = true
256+ }
251257 }
252258 queries [i ], roots [i ] = buildTrees (ri , q )
253259 }
254260
255- return nil
261+ return hasConsistentLocks , nil
256262}
257263
258264func lockCachesAndFillInIDs (queries [][]Subquery , roots [][]int , cachesPresent map [resource ]struct {}) error {
@@ -486,14 +492,16 @@ func fillInIDs(root int, query []Subquery) error {
486492 return nil
487493}
488494
489- func mergeQueries (queries [][]Subquery ) []Subquery {
495+ func mergeQueries (queries [][]Subquery , hasConsistentLocks bool ) []Subquery {
490496 length := 1
491497 for _ , q := range queries {
492498 length += len (q )
493499 }
494500 merged := make ([]Subquery , 0 , length )
495- // always add implied read root, if write root is present it will take precedence
496- merged = append (merged , Subquery {res : root , op : read , id : "." })
501+ // if there are consistent locks, we need to add the root lock to block during shutdown. Inconsistent reads are still allowed.
502+ if hasConsistentLocks {
503+ merged = append (merged , Subquery {res : root , op : read , id : "." })
504+ }
497505 for i , q := range queries {
498506 for j := range q {
499507 q [j ].result = i
0 commit comments