cue/load: load.Instances and resulting build.Instance are not safe for concurrent use
What version of CUE are you using (cue version)?
$ cue version v0.4.3
Does this issue reproduce with the latest release?
Yes
What did you do?
go mod tidy
go run -race .
cmp stdout stdout.golden
-- go.mod --
module github.com/myitcv/playground
go 1.18
require cuelang.org/go v0.4.3
-- main.go --
package main
import (
"fmt"
"sync"
"cuelang.org/go/cue/cuecontext"
"cuelang.org/go/cue/load"
)
const goroutineCount = 5
func main() {
Test1()
Test2()
}
// Separate load.Instances call per goroutine
func Test1() {
var wg sync.WaitGroup
for i := 0; i < goroutineCount; i++ {
wg.Add(1)
go func() {
bps := load.Instances([]string{"."}, nil)
ctx := cuecontext.New()
v := ctx.BuildInstance(bps[0])
fmt.Printf("%v\n", v)
wg.Done()
}()
}
wg.Wait()
}
// Single load.Instances shared by multiple goroutines
func Test2() {
var wg sync.WaitGroup
bps := load.Instances([]string{"."}, nil)
for i := 0; i < goroutineCount; i++ {
wg.Add(1)
go func() {
ctx := cuecontext.New()
v := ctx.BuildInstance(bps[0])
fmt.Printf("%v\n", v)
wg.Done()
}()
}
wg.Wait()
}
-- main.cue --
package main
"hello world"
-- stdout.golden --
"hello world"
"hello world"
"hello world"
"hello world"
"hello world"
"hello world"
"hello world"
"hello world"
"hello world"
"hello world"
What did you expect to see?
A passing test.
What did you see instead?
Errors because of data races in both "tests":
WARNING: DATA RACE
Read at 0x00c000308cb0 by goroutine 13:
cuelang.org/go/internal/core/adt.(*nodeContext).done()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1087 +0x50
cuelang.org/go/internal/core/adt.(*nodeContext).expandOne()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1907 +0x80
cuelang.org/go/internal/core/adt.(*OpContext).Unify()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:254 +0xa64
cuelang.org/go/internal/core/adt.(*Vertex).Finalize()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/adt/composite.go:454 +0xdc
cuelang.org/go/cue.(*Instance).Value()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/instance.go:212 +0x5c
cuelang.org/go/internal/filetypes.parseType()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/filetypes/filetypes.go:286 +0x50
cuelang.org/go/internal/filetypes.ParseFile()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/filetypes/filetypes.go:242 +0x4b4
cuelang.org/go/cue/load.(*loader).importPkg()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/load/import.go:185 +0x1724
cuelang.org/go/cue/load.(*loader).importPathsQuiet()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/load/search.go:373 +0x7fc
cuelang.org/go/cue/load.(*loader).importPaths()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/load/search.go:328 +0x44
cuelang.org/go/cue/load.Instances()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/load/loader.go:67 +0x250
main.Test1.func1()
$WORK/main.go:24 +0x58
Previous write at 0x00c000308cb0 by goroutine 12:
cuelang.org/go/internal/core/adt.(*OpContext).newNodeContext()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:923 +0x44c
cuelang.org/go/internal/core/adt.(*Vertex).getNodeContext()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:935 +0x6c
cuelang.org/go/internal/core/adt.(*OpContext).Unify()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:180 +0xf4
cuelang.org/go/internal/core/adt.(*Vertex).Finalize()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/adt/composite.go:454 +0xdc
cuelang.org/go/cue.(*Instance).Value()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/instance.go:212 +0x5c
cuelang.org/go/internal/filetypes.parseType()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/filetypes/filetypes.go:286 +0x50
cuelang.org/go/internal/filetypes.ParseFile()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/filetypes/filetypes.go:242 +0x4b4
cuelang.org/go/cue/load.(*loader).importPkg()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/load/import.go:185 +0x1724
cuelang.org/go/cue/load.(*loader).importPathsQuiet()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/load/search.go:373 +0x7fc
cuelang.org/go/cue/load.(*loader).importPaths()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/load/search.go:328 +0x44
cuelang.org/go/cue/load.Instances()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/load/loader.go:67 +0x250
main.Test1.func1()
$WORK/main.go:24 +0x58
WARNING: DATA RACE
Read at 0x00c00061bc00 by goroutine 27:
cuelang.org/go/internal/core/runtime.resolveFile()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/runtime/resolve.go:63 +0x8c
cuelang.org/go/internal/core/runtime.(*Runtime).ResolveFiles()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/runtime/resolve.go:50 +0x36c
cuelang.org/go/internal/core/runtime.(*Runtime).Build()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/runtime/build.go:66 +0x1a0
cuelang.org/go/cue.(*Context).BuildInstance()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/context.go:122 +0x140
main.Test2.func1()
$WORK/main.go:42 +0x394
Previous write at 0x00c00061bc00 by goroutine 25:
cuelang.org/go/internal/core/runtime.resolveFile()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/runtime/resolve.go:158 +0x11bc
cuelang.org/go/internal/core/runtime.(*Runtime).ResolveFiles()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/runtime/resolve.go:50 +0x36c
cuelang.org/go/internal/core/runtime.(*Runtime).Build()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/runtime/build.go:66 +0x1a0
cuelang.org/go/cue.(*Context).BuildInstance()
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/context.go:122 +0x140
main.Test2.func1()
$WORK/main.go:42 +0x394
Including, on occasion, the following panic:
panic: runtime error: index out of range [0] with length 0
goroutine 38 [running]:
cuelang.org/go/internal/core/adt.(*nodeContext).insertConjuncts(0xc0000b8000)
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:382 +0x2a0
cuelang.org/go/internal/core/adt.(*OpContext).Unify(0xc0004320d0, 0xc000247050, 0x5)
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:191 +0x254
cuelang.org/go/internal/core/adt.(*Vertex).Finalize(...)
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/core/adt/composite.go:454
cuelang.org/go/cue.(*Instance).Value(0xc0002ee460)
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/instance.go:212 +0xe0
cuelang.org/go/internal/filetypes.parseType({0x0, 0x0}, 0x0)
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/filetypes/filetypes.go:286 +0x54
cuelang.org/go/internal/filetypes.ParseFile({0xc00042a42c, 0x6}, 0x2b?)
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/internal/filetypes/filetypes.go:242 +0x4b8
cuelang.org/go/cue/load.(*loader).importPkg(0xc00042c280, {0x0?, 0x7ab9d0?}, 0xc000430000)
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/load/import.go:185 +0x1728
cuelang.org/go/cue/load.(*loader).importPathsQuiet(0xc00042c280, {0xc00041bfa0, 0x1, 0x1})
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/load/search.go:373 +0x800
cuelang.org/go/cue/load.(*loader).importPaths(0x7ab753?, {0xc00041bfa0, 0x1, 0x1})
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/load/search.go:328 +0x48
cuelang.org/go/cue/load.Instances({0xc000399fa0, 0x1, 0x1}, 0x0)
/home/myitcv/gostuff/pkg/mod/cuelang.org/[email protected]/cue/load/loader.go:67 +0x254
main.Test1.func1()
$WORK/main.go:24 +0x5c
created by main.Test1
$WORK/main.go:23 +0x54
exit status 2
Here's a simpler reproducer. There's a race inside load.Instances itself (there might be more at a later stage too).
go mod tidy
go run -race .
cmp stdout stdout.golden
-- go.mod --
module github.com/myitcv/playground
go 1.20
require cuelang.org/go v0.5.0
-- main.go --
package main
import (
"sync"
"cuelang.org/go/cue/load"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 2; i++ {
wg.Add(1)
go func() {
load.Instances([]string{"."}, nil)
wg.Done()
}()
}
wg.Wait()
}
-- main.cue --
"hello world"
-- stdout.golden --
Roger's solved the race in Test1, which was also reported in https://github.com/cue-lang/cue/issues/460.
The race in Test2 is still present as of afe322d6497e6727c2bd6f5f423f966b30f03f8d; this is because Runtime.Build calls Runtime.ResolveFiles, which modifies the ast.File.Unresolved slice in-place.
I guess my question in terms of API design would be - why would any end user be trying to build/compile the same build.Instance multiple times concurrently? It seems to me like one may want to build multiple instances concurrently, but each only once, not multiple times. But I'm not sure there is a value in adding any sort of mutexes or atomics to protect against "double builds" of a single instance, because I'm not sure when that would ever be useful.
With version 0.9.2, I've just observed a race detection when two Go tests were run in parallel, each performing load.Instances, then cuecontext.New().BuildInstance() (so like in Test1). Here's an extract from the logs:
==================
WARNING: DATA RACE
Write at 0x0000016402b0 by goroutine 25:
cuelang.org/go/internal/pkg.(*Package).MustCompile()
/go/pkg/mod/cuelang.org/[email protected]/internal/pkg/builtin.go:73 +0x33a
cuelang.org/go/internal/pkg.Register.func1()
/go/pkg/mod/cuelang.org/[email protected]/internal/pkg/register.go:28 +0xab
cuelang.org/go/internal/core/runtime.(*Runtime).LoadImport()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/runtime/imports.go:145 +0x22f
cuelang.org/go/internal/core/adt.(*ImportReference).resolve()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:846 +0xa6
cuelang.org/go/internal/core/adt.(*OpContext).unifyNode()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:838 +0x3b5
cuelang.org/go/internal/core/adt.(*OpContext).node()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:1061 +0x88
cuelang.org/go/internal/core/adt.(*SelectorExpr).resolve()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:1007 +0xbc
cuelang.org/go/internal/core/adt.(*OpContext).evalState()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:706 +0x3e5
cuelang.org/go/internal/core/adt.(*OpContext).value()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:653 +0x44
cuelang.org/go/internal/core/adt.(*CallExpr).evaluate()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:1487 +0x89
cuelang.org/go/internal/core/adt.(*OpContext).evalState()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:702 +0xf48
cuelang.org/go/internal/core/adt.(*OpContext).evaluateRec()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:635 +0x164
cuelang.org/go/internal/core/adt.(*nodeContext).evalExpr()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1682 +0x23d
cuelang.org/go/internal/core/adt.(*nodeContext).addExprConjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1621 +0x74e
cuelang.org/go/internal/core/adt.(*nodeContext).insertConjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:413 +0x326
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:247 +0x19fc
cuelang.org/go/internal/core/adt.(*nodeContext).completeArcs()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:811 +0x446
cuelang.org/go/internal/core/adt.(*nodeContext).postDisjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:595 +0x486
cuelang.org/go/internal/core/adt.(*nodeContext).expandDisjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/disjunct.go:176 +0x70a
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:302 +0xcea
cuelang.org/go/internal/core/adt.(*nodeContext).completeArcs()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:811 +0x446
cuelang.org/go/internal/core/adt.(*nodeContext).postDisjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:595 +0x486
cuelang.org/go/internal/core/adt.(*nodeContext).expandDisjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/disjunct.go:176 +0x70a
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:302 +0xcea
cuelang.org/go/internal/core/adt.(*Vertex).Finalize()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/composite.go:816 +0xa4
cuelang.org/go/internal/core/adt.(*nodeContext).evalExpr()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1668 +0x9b6
cuelang.org/go/internal/core/adt.(*nodeContext).addExprConjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1621 +0x74e
cuelang.org/go/internal/core/adt.(*nodeContext).insertConjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:413 +0x326
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:247 +0x19fc
cuelang.org/go/internal/core/adt.(*nodeContext).completeArcs()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:811 +0x446
cuelang.org/go/internal/core/adt.(*nodeContext).postDisjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:595 +0x486
cuelang.org/go/internal/core/adt.(*nodeContext).expandDisjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/disjunct.go:176 +0x70a
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:302 +0xcea
cuelang.org/go/internal/core/adt.(*nodeContext).completeArcs()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:811 +0x446
cuelang.org/go/internal/core/adt.(*nodeContext).postDisjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:595 +0x486
cuelang.org/go/internal/core/adt.(*nodeContext).expandDisjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/disjunct.go:176 +0x70a
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:302 +0xcea
cuelang.org/go/internal/core/adt.(*Vertex).Finalize()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/composite.go:816 +0xa4
cuelang.org/go/cue.newVertexRoot()
/go/pkg/mod/cuelang.org/[email protected]/cue/types.go:602 +0x3e
cuelang.org/go/cue.newValueRoot()
/go/pkg/mod/cuelang.org/[email protected]/cue/types.go:611 +0x77
cuelang.org/go/cue.(*Context).make()
/go/pkg/mod/cuelang.org/[email protected]/cue/context.go:257 +0xcc
cuelang.org/go/cue.(*Context).BuildInstance()
/go/pkg/mod/cuelang.org/[email protected]/cue/context.go:130 +0x224
...
Previous read at 0x0000016402b0 by goroutine 8:
cuelang.org/go/internal/pkg.ToBuiltin()
/go/pkg/mod/cuelang.org/[email protected]/internal/pkg/builtin.go:124 +0x63d
cuelang.org/go/internal/pkg.(*Package).MustCompile()
/go/pkg/mod/cuelang.org/[email protected]/internal/pkg/builtin.go:81 +0x4d9
cuelang.org/go/internal/pkg.Register.func1()
/go/pkg/mod/cuelang.org/[email protected]/internal/pkg/register.go:28 +0xab
cuelang.org/go/internal/core/runtime.(*Runtime).LoadImport()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/runtime/imports.go:145 +0x22f
cuelang.org/go/internal/core/adt.(*ImportReference).resolve()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:846 +0xa6
cuelang.org/go/internal/core/adt.(*OpContext).unifyNode()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:838 +0x3b5
cuelang.org/go/internal/core/adt.(*OpContext).node()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:1061 +0x88
cuelang.org/go/internal/core/adt.(*SelectorExpr).resolve()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:1007 +0xbc
cuelang.org/go/internal/core/adt.(*OpContext).evalState()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:706 +0x3e5
cuelang.org/go/internal/core/adt.(*OpContext).value()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:653 +0x44
cuelang.org/go/internal/core/adt.(*CallExpr).evaluate()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:1487 +0x89
cuelang.org/go/internal/core/adt.(*OpContext).evalState()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:702 +0xf48
cuelang.org/go/internal/core/adt.(*OpContext).evaluateRec()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:635 +0x164
cuelang.org/go/internal/core/adt.(*nodeContext).evalExpr()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1682 +0x23d
cuelang.org/go/internal/core/adt.(*nodeContext).addExprConjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1621 +0x74e
cuelang.org/go/internal/core/adt.(*nodeContext).insertConjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:413 +0x326
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:247 +0x19fc
cuelang.org/go/internal/core/adt.(*nodeContext).completeArcs()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:811 +0x446
cuelang.org/go/internal/core/adt.(*nodeContext).postDisjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:595 +0x486
cuelang.org/go/internal/core/adt.(*nodeContext).expandDisjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/disjunct.go:176 +0x70a
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:302 +0xcea
cuelang.org/go/internal/core/adt.(*nodeContext).completeArcs()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:811 +0x446
cuelang.org/go/internal/core/adt.(*nodeContext).postDisjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:595 +0x486
cuelang.org/go/internal/core/adt.(*nodeContext).expandDisjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/disjunct.go:176 +0x70a
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:302 +0xcea
cuelang.org/go/internal/core/adt.(*Vertex).Finalize()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/composite.go:816 +0xa4
cuelang.org/go/internal/core/adt.(*nodeContext).evalExpr()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1668 +0x9b6
cuelang.org/go/internal/core/adt.(*nodeContext).addExprConjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1621 +0x74e
cuelang.org/go/internal/core/adt.(*nodeContext).insertConjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:413 +0x326
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:247 +0x19fc
cuelang.org/go/internal/core/adt.(*nodeContext).completeArcs()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:811 +0x446
cuelang.org/go/internal/core/adt.(*nodeContext).postDisjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:595 +0x486
cuelang.org/go/internal/core/adt.(*nodeContext).expandDisjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/disjunct.go:176 +0x70a
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:302 +0xcea
cuelang.org/go/internal/core/adt.(*nodeContext).completeArcs()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:811 +0x446
cuelang.org/go/internal/core/adt.(*nodeContext).postDisjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:595 +0x486
cuelang.org/go/internal/core/adt.(*nodeContext).expandDisjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/disjunct.go:176 +0x70a
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:302 +0xcea
cuelang.org/go/internal/core/adt.(*Vertex).Finalize()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/composite.go:816 +0xa4
cuelang.org/go/cue.newVertexRoot()
/go/pkg/mod/cuelang.org/[email protected]/cue/types.go:602 +0x3e
cuelang.org/go/cue.newValueRoot()
/go/pkg/mod/cuelang.org/[email protected]/cue/types.go:611 +0x77
cuelang.org/go/cue.(*Context).make()
/go/pkg/mod/cuelang.org/[email protected]/cue/context.go:257 +0xcc
cuelang.org/go/cue.(*Context).BuildInstance()
/go/pkg/mod/cuelang.org/[email protected]/cue/context.go:130 +0x224
...
testing.tRunner()
/usr/local/go/src/testing/testing.go:1689 +0x21e
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:1742 +0x44
Goroutine 25 (running) created at:
some/package.TestNewResolver.func1()
/some/file_test.go:50 +0x57
testing.tRunner()
/usr/local/go/src/testing/testing.go:1689 +0x21e
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:1742 +0x44
Goroutine 8 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:1742 +0x825
testing.runTests.func1()
/usr/local/go/src/testing/testing.go:2161 +0x85
testing.tRunner()
/usr/local/go/src/testing/testing.go:1689 +0x21e
testing.runTests()
/usr/local/go/src/testing/testing.go:2159 +0x8be
testing.(*M).Run()
/usr/local/go/src/testing/testing.go:2027 +0xf17
main.main()
_testmain.go:83 +0x2e4
==================
==================
WARNING: DATA RACE
Write at 0x00000163f110 by goroutine 8:
cuelang.org/go/internal/pkg.(*Package).MustCompile()
/go/pkg/mod/cuelang.org/[email protected]/internal/pkg/builtin.go:73 +0x33a
cuelang.org/go/internal/pkg.Register.func1()
/go/pkg/mod/cuelang.org/[email protected]/internal/pkg/register.go:28 +0xab
cuelang.org/go/internal/core/runtime.(*Runtime).LoadImport()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/runtime/imports.go:145 +0x22f
cuelang.org/go/internal/core/adt.(*ImportReference).resolve()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:846 +0xa6
cuelang.org/go/internal/core/adt.(*OpContext).unifyNode()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:838 +0x3b5
cuelang.org/go/internal/core/adt.(*OpContext).node()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:1061 +0x88
cuelang.org/go/internal/core/adt.(*SelectorExpr).resolve()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:1007 +0xbc
cuelang.org/go/internal/core/adt.(*OpContext).evalState()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:706 +0x3e5
cuelang.org/go/internal/core/adt.(*OpContext).value()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:653 +0x44
cuelang.org/go/internal/core/adt.(*CallExpr).evaluate()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:1487 +0x89
cuelang.org/go/internal/core/adt.(*OpContext).evalState()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:702 +0xf48
cuelang.org/go/internal/core/adt.(*OpContext).evaluateRec()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:635 +0x164
cuelang.org/go/internal/core/adt.(*nodeContext).evalExpr()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1682 +0x23d
cuelang.org/go/internal/core/adt.(*nodeContext).addExprConjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1621 +0x74e
cuelang.org/go/internal/core/adt.(*nodeContext).insertConjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:413 +0x326
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:247 +0x19fc
cuelang.org/go/internal/core/adt.(*nodeContext).completeArcs()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:811 +0x446
cuelang.org/go/internal/core/adt.(*nodeContext).postDisjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:595 +0x486
cuelang.org/go/internal/core/adt.(*nodeContext).expandDisjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/disjunct.go:176 +0x70a
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:302 +0xcea
cuelang.org/go/internal/core/adt.(*nodeContext).completeArcs()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:811 +0x446
cuelang.org/go/internal/core/adt.(*nodeContext).postDisjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:595 +0x486
cuelang.org/go/internal/core/adt.(*nodeContext).expandDisjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/disjunct.go:176 +0x70a
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:302 +0xcea
cuelang.org/go/internal/core/adt.(*nodeContext).completeArcs()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:811 +0x446
cuelang.org/go/internal/core/adt.(*nodeContext).postDisjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:595 +0x486
cuelang.org/go/internal/core/adt.(*nodeContext).expandDisjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/disjunct.go:176 +0x70a
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:302 +0xcea
cuelang.org/go/internal/core/adt.(*Vertex).Finalize()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/composite.go:816 +0xa4
cuelang.org/go/cue.newVertexRoot()
/go/pkg/mod/cuelang.org/[email protected]/cue/types.go:602 +0x3e
cuelang.org/go/cue.newValueRoot()
/go/pkg/mod/cuelang.org/[email protected]/cue/types.go:611 +0x77
cuelang.org/go/cue.(*Context).make()
/go/pkg/mod/cuelang.org/[email protected]/cue/context.go:257 +0xcc
cuelang.org/go/cue.(*Context).BuildInstance()
/go/pkg/mod/cuelang.org/[email protected]/cue/context.go:130 +0x224
...
testing.tRunner()
/usr/local/go/src/testing/testing.go:1689 +0x21e
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:1742 +0x44
Previous read at 0x00000163f110 by goroutine 25:
cuelang.org/go/internal/pkg.ToBuiltin()
/go/pkg/mod/cuelang.org/[email protected]/internal/pkg/builtin.go:124 +0x63d
cuelang.org/go/internal/pkg.(*Package).MustCompile()
/go/pkg/mod/cuelang.org/[email protected]/internal/pkg/builtin.go:81 +0x4d9
cuelang.org/go/internal/pkg.Register.func1()
/go/pkg/mod/cuelang.org/[email protected]/internal/pkg/register.go:28 +0xab
cuelang.org/go/internal/core/runtime.(*Runtime).LoadImport()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/runtime/imports.go:145 +0x22f
cuelang.org/go/internal/core/adt.(*ImportReference).resolve()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:846 +0xa6
cuelang.org/go/internal/core/adt.(*OpContext).unifyNode()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:838 +0x3b5
cuelang.org/go/internal/core/adt.(*OpContext).node()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:1061 +0x88
cuelang.org/go/internal/core/adt.(*SelectorExpr).resolve()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:1007 +0xbc
cuelang.org/go/internal/core/adt.(*OpContext).evalState()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:706 +0x3e5
cuelang.org/go/internal/core/adt.(*OpContext).value()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:653 +0x44
cuelang.org/go/internal/core/adt.(*CallExpr).evaluate()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:1487 +0x89
cuelang.org/go/internal/core/adt.(*OpContext).evalState()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:702 +0xf48
cuelang.org/go/internal/core/adt.(*OpContext).evaluateRec()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:635 +0x164
cuelang.org/go/internal/core/adt.(*nodeContext).evalExpr()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1682 +0x23d
cuelang.org/go/internal/core/adt.(*nodeContext).addExprConjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1621 +0x74e
cuelang.org/go/internal/core/adt.(*nodeContext).insertConjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:413 +0x326
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:247 +0x19fc
cuelang.org/go/internal/core/adt.(*nodeContext).completeArcs()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:811 +0x446
cuelang.org/go/internal/core/adt.(*nodeContext).postDisjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:595 +0x486
cuelang.org/go/internal/core/adt.(*nodeContext).expandDisjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/disjunct.go:176 +0x70a
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:302 +0xcea
cuelang.org/go/internal/core/adt.(*nodeContext).completeArcs()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:811 +0x446
cuelang.org/go/internal/core/adt.(*nodeContext).postDisjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:595 +0x486
cuelang.org/go/internal/core/adt.(*nodeContext).expandDisjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/disjunct.go:176 +0x70a
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:302 +0xcea
cuelang.org/go/internal/core/adt.(*nodeContext).completeArcs()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:811 +0x446
cuelang.org/go/internal/core/adt.(*nodeContext).postDisjunct()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:595 +0x486
cuelang.org/go/internal/core/adt.(*nodeContext).expandDisjuncts()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/disjunct.go:176 +0x70a
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:302 +0xcea
cuelang.org/go/internal/core/adt.(*Vertex).Finalize()
/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/composite.go:816 +0xa4
cuelang.org/go/cue.newVertexRoot()
/go/pkg/mod/cuelang.org/[email protected]/cue/types.go:602 +0x3e
cuelang.org/go/cue.newValueRoot()
/go/pkg/mod/cuelang.org/[email protected]/cue/types.go:611 +0x77
cuelang.org/go/cue.(*Context).make()
/go/pkg/mod/cuelang.org/[email protected]/cue/context.go:257 +0xcc
cuelang.org/go/cue.(*Context).BuildInstance()
/go/pkg/mod/cuelang.org/[email protected]/cue/context.go:130 +0x224
...
Goroutine 8 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:1742 +0x825
testing.runTests.func1()
/usr/local/go/src/testing/testing.go:2161 +0x85
testing.tRunner()
/usr/local/go/src/testing/testing.go:1689 +0x21e
testing.runTests()
/usr/local/go/src/testing/testing.go:2159 +0x8be
testing.(*M).Run()
/usr/local/go/src/testing/testing.go:2027 +0xf17
main.main()
_testmain.go:83 +0x2e4
Goroutine 25 (running) created at:
some/package.TestNewResolver.func1()
/some/file_test.go:50 +0x57
testing.tRunner()
/usr/local/go/src/testing/testing.go:1689 +0x21e
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:1742 +0x44
==================
With version 0.9.2, I've just observed a race detection when two Go tests were run in parallel, each performing
load.Instances, thencuecontext.New().BuildInstance()(so like in Test1). Here's an extract from the logs:
Would you be able to share some code to reproduce this race, by any chance?
It will be difficult. Are you interested more in the CUE or Go part?
@roman-mazur more the Go part. I assume you have concurrent Go tests which compile/load CUE code, and this CUE code imports CUE standard library packages?
The function that uses the load package looks the following way:
func load(someCueString1, someCueString1 string) cue.Value {
cfg := &load.Config{
Package: "config",
Dir: tmpDir,
Overlay: make(map[string]load.Source),
}
cfg.Overlay[filepath.Join(tmpDir, "file1.cue")] = load.FromString(someCueString1)
cfg.Overlay[filepath.Join(tmpDir, "file2.cue")] = load.FromString(someCueString2)
instances := load.Instances([]string{"file1.cue", "file2.cue"}, cfg)
return cuecontext.New().BuildInstance(instances[0])
}
I'm also experiencing this issue with tests and was able to reproduce it for tests but not with go run. Here’s a minimal example:
// main.go
package main
import (
"cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
"cuelang.org/go/cue/load"
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
val, err := GetCueVal()
if err != nil {
panic(err)
}
fmt.Println(val)
}()
wg.Wait()
}
}
func GetCueVal() (cue.Value, error) {
ctx := cuecontext.New()
insts := load.Instances([]string{"."}, nil)
val := ctx.BuildInstance(insts[0])
if val.Err() != nil {
return cue.Value{}, val.Err()
}
return val, nil
}
// main_test.go
package main
import (
"cuelang.org/go/cue/cuecontext"
"cuelang.org/go/cue/load"
"github.com/stretchr/testify/assert"
"testing"
)
func TestCueLoad(t *testing.T) {
t.Parallel()
for i := 0; i < 10; i++ {
t.Run("test number "+string(rune(i)), func(t *testing.T) {
t.Parallel()
ctx := cuecontext.New()
insts := load.Instances([]string{"."}, nil)
v := ctx.BuildInstance(insts[0])
assert.NotEmpty(t, v)
})
}
}
// file.cue
package example
import "list"
l: [1, 2, 3]
#b: [1,2,3]
for num in l {
#b: list.Contains(num)
}
Running go run -race . works fine, but running go test -race . outputs:
==================
WARNING: DATA RACE
Write at 0x000001699b50 by goroutine 9:
cuelang.org/go/internal/pkg.(*Package).MustCompile()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/pkg/builtin.go:73 +0x33a
cuelang.org/go/internal/pkg.Register.func1()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/pkg/register.go:28 +0xab
cuelang.org/go/internal/core/runtime.(*Runtime).LoadImport()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/runtime/imports.go:145 +0x22f
cuelang.org/go/internal/core/adt.(*ImportReference).resolve()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:846 +0xa6
cuelang.org/go/internal/core/adt.(*OpContext).unifyNode()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:838 +0x3b5
cuelang.org/go/internal/core/adt.(*OpContext).node()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:1061 +0x88
cuelang.org/go/internal/core/adt.(*SelectorExpr).resolve()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:1007 +0xbc
cuelang.org/go/internal/core/adt.(*OpContext).evalState()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:706 +0x3e5
cuelang.org/go/internal/core/adt.(*OpContext).value()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:653 +0x44
cuelang.org/go/internal/core/adt.(*CallExpr).evaluate()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:1487 +0x89
cuelang.org/go/internal/core/adt.(*OpContext).evalState()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:702 +0xf48
cuelang.org/go/internal/core/adt.(*OpContext).evaluateRec()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:635 +0x164
cuelang.org/go/internal/core/adt.(*nodeContext).evalExpr()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1684 +0x23d
cuelang.org/go/internal/core/adt.(*nodeContext).addExprConjunct()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1623 +0x74e
cuelang.org/go/internal/core/adt.(*nodeContext).processComprehensionInner()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/comprehension.go:517 +0xcf0
cuelang.org/go/internal/core/adt.(*nodeContext).processComprehension()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/comprehension.go:407 +0x39
cuelang.org/go/internal/core/adt.(*nodeContext).injectComprehensions()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/comprehension.go:352 +0x1bc
cuelang.org/go/internal/core/adt.(*nodeContext).expandOne()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:2204 +0x17c
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:275 +0xbeb
cuelang.org/go/internal/core/adt.(*nodeContext).completeArcs()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:811 +0x446
cuelang.org/go/internal/core/adt.(*nodeContext).postDisjunct()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:595 +0x486
cuelang.org/go/internal/core/adt.(*nodeContext).expandDisjuncts()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/disjunct.go:178 +0x6ea
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:302 +0xcea
cuelang.org/go/internal/core/adt.(*Vertex).Finalize()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/composite.go:822 +0xa4
cuelang.org/go/cue.newVertexRoot()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/cue/types.go:602 +0x3e
cuelang.org/go/cue.newValueRoot()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/cue/types.go:611 +0x77
cuelang.org/go/cue.(*Context).make()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/cue/context.go:252 +0xcc
cuelang.org/go/cue.(*Context).BuildInstance()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/cue/context.go:128 +0x224
cue_test_race.TestCueLoad.func1()
/home/userName/repos/testings/cue_test_race/main_test.go:18 +0xa7
testing.tRunner()
/usr/local/go/src/testing/testing.go:1690 +0x226
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:1743 +0x44
Previous write at 0x000001699b50 by goroutine 18:
cuelang.org/go/internal/pkg.(*Package).MustCompile()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/pkg/builtin.go:73 +0x33a
cuelang.org/go/internal/pkg.Register.func1()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/pkg/register.go:28 +0xab
cuelang.org/go/internal/core/runtime.(*Runtime).LoadImport()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/runtime/imports.go:145 +0x22f
cuelang.org/go/internal/core/adt.(*ImportReference).resolve()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:846 +0xa6
cuelang.org/go/internal/core/adt.(*OpContext).unifyNode()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:838 +0x3b5
cuelang.org/go/internal/core/adt.(*OpContext).node()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:1061 +0x88
cuelang.org/go/internal/core/adt.(*SelectorExpr).resolve()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:1007 +0xbc
cuelang.org/go/internal/core/adt.(*OpContext).evalState()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:706 +0x3e5
cuelang.org/go/internal/core/adt.(*OpContext).value()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:653 +0x44
cuelang.org/go/internal/core/adt.(*CallExpr).evaluate()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/expr.go:1487 +0x89
cuelang.org/go/internal/core/adt.(*OpContext).evalState()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:702 +0xf48
cuelang.org/go/internal/core/adt.(*OpContext).evaluateRec()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/context.go:635 +0x164
cuelang.org/go/internal/core/adt.(*nodeContext).evalExpr()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1684 +0x23d
cuelang.org/go/internal/core/adt.(*nodeContext).addExprConjunct()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:1623 +0x74e
cuelang.org/go/internal/core/adt.(*nodeContext).processComprehensionInner()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/comprehension.go:517 +0xcf0
cuelang.org/go/internal/core/adt.(*nodeContext).processComprehension()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/comprehension.go:407 +0x39
cuelang.org/go/internal/core/adt.(*nodeContext).injectComprehensions()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/comprehension.go:352 +0x1bc
cuelang.org/go/internal/core/adt.(*nodeContext).expandOne()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:2204 +0x17c
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:275 +0xbeb
cuelang.org/go/internal/core/adt.(*nodeContext).completeArcs()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:811 +0x446
cuelang.org/go/internal/core/adt.(*nodeContext).postDisjunct()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:595 +0x486
cuelang.org/go/internal/core/adt.(*nodeContext).expandDisjuncts()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/disjunct.go:178 +0x6ea
cuelang.org/go/internal/core/adt.(*OpContext).unify()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/eval.go:302 +0xcea
cuelang.org/go/internal/core/adt.(*Vertex).Finalize()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/internal/core/adt/composite.go:822 +0xa4
cuelang.org/go/cue.newVertexRoot()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/cue/types.go:602 +0x3e
cuelang.org/go/cue.newValueRoot()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/cue/types.go:611 +0x77
cuelang.org/go/cue.(*Context).make()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/cue/context.go:252 +0xcc
cuelang.org/go/cue.(*Context).BuildInstance()
/home/userName/go/pkg/mod/cuelang.org/[email protected]/cue/context.go:128 +0x224
cue_test_race.TestCueLoad.func1()
/home/userName/repos/testings/cue_test_race/main_test.go:18 +0xa7
testing.tRunner()
/usr/local/go/src/testing/testing.go:1690 +0x226
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:1743 +0x44
Goroutine 9 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:1743 +0x825
cue_test_race.TestCueLoad()
/home/userName/repos/testings/cue_test_race/main_test.go:14 +0x74
testing.tRunner()
/usr/local/go/src/testing/testing.go:1690 +0x226
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:1743 +0x44
Goroutine 18 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:1743 +0x825
cue_test_race.TestCueLoad()
/home/userName/repos/testings/cue_test_race/main_test.go:14 +0x74
testing.tRunner()
/usr/local/go/src/testing/testing.go:1690 +0x226
testing.(*T).Run.gowrap1()
/usr/local/go/src/testing/testing.go:1743 +0x44
==================
==================
--- FAIL: TestCueLoad (0.00s)
--- FAIL: TestCueLoad/test_number_\x01 (0.05s)
testing.go:1399: race detected during execution of test
--- FAIL: TestCueLoad/test_number__ (0.07s)
testing.go:1399: race detected during execution of test
--- FAIL: TestCueLoad/test_number_\x04 (0.08s)
testing.go:1399: race detected during execution of test
--- FAIL: TestCueLoad/test_number_\x06 (0.08s)
testing.go:1399: race detected during execution of test
--- FAIL: TestCueLoad/test_number_\b (0.08s)
testing.go:1399: race detected during execution of test
--- FAIL: TestCueLoad/test_number_\x00 (0.08s)
testing.go:1399: race detected during execution of test
--- FAIL: TestCueLoad/test_number_\a (0.08s)
testing.go:1399: race detected during execution of test
--- FAIL: TestCueLoad/test_number_\x03 (0.08s)
testing.go:1399: race detected during execution of test
--- FAIL: TestCueLoad/test_number_\x05 (0.08s)
testing.go:1399: race detected during execution of test
--- FAIL: TestCueLoad/test_number_\x02 (0.08s)
testing.go:1399: race detected during execution of test
FAIL
FAIL cue_test_race 0.102s
FAIL
...
~Haven't been able to reproduce it with 0.10.0 so far.~
UPD: never mind, reproduced with 0.10.0, same as reported in https://github.com/cue-lang/cue/issues/1746#issuecomment-2327483444
@mvdan
I guess my question in terms of API design would be - why would any end user be trying to build/compile the same build.Instance multiple times concurrently? It seems to me like one may want to build multiple instances concurrently, but each only once, not multiple times. But I'm not sure there is a value in adding any sort of mutexes or atomics to protect against "double builds" of a single instance, because I'm not sure when that would ever be useful.
Having just run across this once more, here's one answer: given that cue.Context is not safe for concurrent use, if one does wish to run CUE evaluations concurrently on a package, it makes sense to load the instance for that package once, then use that instance multiple times as an argument to cue.Context.BuildInstance, once for each concurrent Context.
In terms of API, it would be good if whatever future API was used would return something "resolved enough" from the loader API such that the future equivalent of cue.Context.BuildInstance would not need to mutate the underlying instance. That would probably involve a little extra work to look up symbols when creating the cue.Value from the *ast.File but that probably wouldn't have significant impact on overall runtime.