[go: up one dir, main page]

Cached cat-file processes may be "dirtied" after they have been put back into the cache

We currently use the following logic to return used git cat-file --batch processes into the global cache:

// c is a catfile instance
<- ctx.Done()
if isDirty(c) {
  // dirty c cannot be reused
  return
}
cache.Add(c)

The problem is that another goroutine may still be holding c, and may dirty it after our if isDirty(c) check. This will then cause an "undeserved" error for the next request that uses c.

As a solution I propose:

  • rename Batch to batchCore, and only cache batchCore
  • create new type Batch struct which contains *batchCore field
  • every consumer gets a fresh *Batch instance
  • add field token int to batchCore and Batch
  • at checkout, c.token = c.batchCore.token
  • all methods on *Batch start by checking if c.token == c.batchCore.token
  • at checkin, before we do the isDirty check, increment c.batchCore.token

This way we can cut off old consumers from using a *batchCore we are returning to the cache.

Edited by Jacob Vosmaer