jeudi 22 février 2018

How to test unlikely concurrent scenarios?

For example, map access like this:

func (pool *fPool) fetch(url string) *ResultPromise {
    pool.cacheLock.RLock()
    if rp, pres := pool.cache[url]; pres {
        pool.cacheLock.RUnlock()
        return rp
    }
    pool.cacheLock.RUnlock()
    pool.cacheLock.Lock()
    if rp, pres := pool.cache[url]; pres {
        pool.cacheLock.Unlock()
        // Skip adding url if someone snuck it in between RUnlock an Lock
        return rp
    }
    rp := newPromise()
    pool.cache[url] = rp
    pool.cacheLock.Unlock()
    pool.c <- fetchWork{rp, url}
    return rp
}

Here, the contents of the second if condition are not covered. However, by placing breakpoints it's trivial to end up in that block.

The example isn't contrived, because:

  1. If we skip the RLock, the map will be unnecessarily locked when the workload is mostly reads.
  2. If we skip the second if,the most expensive work (handled by pool.c <- fetchWork{rp, url} in this case) can happen more than once for the same key, which is unacceptable.

Aucun commentaire:

Enregistrer un commentaire