mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
Ensure deterministic execution, for tests
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
This commit is contained in:
parent
6dcebc9e25
commit
efcd876b50
|
@ -93,6 +93,11 @@ func (p *postingsForMatcherPromise) result(ctx context.Context) (index.Postings,
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return nil, ctx.Err()
|
return nil, ctx.Err()
|
||||||
case <-p.done:
|
case <-p.done:
|
||||||
|
// Checking context error is necessary for deterministic tests,
|
||||||
|
// as channel selection order is random
|
||||||
|
if ctx.Err() != nil {
|
||||||
|
return nil, ctx.Err()
|
||||||
|
}
|
||||||
if p.err != nil {
|
if p.err != nil {
|
||||||
return nil, p.err
|
return nil, p.err
|
||||||
}
|
}
|
||||||
|
@ -107,12 +112,18 @@ func (c *PostingsForMatchersCache) postingsForMatchersPromise(ix IndexPostingsRe
|
||||||
key := matchersKey(ms)
|
key := matchersKey(ms)
|
||||||
oldPromise, loaded := c.calls.LoadOrStore(key, promise)
|
oldPromise, loaded := c.calls.LoadOrStore(key, promise)
|
||||||
if loaded {
|
if loaded {
|
||||||
promise = oldPromise.(*postingsForMatcherPromise)
|
// promise was not stored, we return a previously stored promise, that's possibly being fulfilled in another goroutine
|
||||||
return promise.result
|
close(promise.done)
|
||||||
|
return oldPromise.(*postingsForMatcherPromise).result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// promise was stored, close its channel after fulfilment
|
||||||
defer close(promise.done)
|
defer close(promise.done)
|
||||||
|
|
||||||
// FIXME: do we need to cancel the call to postingsForMatchers if all the callers waiting for the result have cancelled their context?
|
// Don't let context cancellation fail the promise, since it may be used by multiple goroutines, each with
|
||||||
|
// its own context. Also, keep the call independent of this particular context, since the promise will be reused.
|
||||||
|
// FIXME: do we need to cancel the call to postingsForMatchers if all the callers waiting for the result have
|
||||||
|
// cancelled their context?
|
||||||
if postings, err := c.postingsForMatchers(context.Background(), ix, ms...); err != nil {
|
if postings, err := c.postingsForMatchers(context.Background(), ix, ms...); err != nil {
|
||||||
promise.err = err
|
promise.err = err
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -352,7 +352,7 @@ func TestPostingsForMatchersCache(t *testing.T) {
|
||||||
ctx1, cancel := context.WithCancel(context.Background())
|
ctx1, cancel := context.WithCancel(context.Background())
|
||||||
cancel()
|
cancel()
|
||||||
_, err := c.PostingsForMatchers(ctx1, indexForPostingsMock{}, true, matchers...)
|
_, err := c.PostingsForMatchers(ctx1, indexForPostingsMock{}, true, matchers...)
|
||||||
require.Equal(t, context.Canceled, err)
|
require.ErrorIs(t, err, context.Canceled)
|
||||||
|
|
||||||
ctx2 := context.Background()
|
ctx2 := context.Background()
|
||||||
actualPostings, err := c.PostingsForMatchers(ctx2, indexForPostingsMock{}, true, matchers...)
|
actualPostings, err := c.PostingsForMatchers(ctx2, indexForPostingsMock{}, true, matchers...)
|
||||||
|
|
Loading…
Reference in a new issue