solver: solve synchronously

This forces Solve() to be synchronous and ensures operations don't get
discarded because of optimizations.

Improves fix for #14

Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
Andrea Luzzardi 2021-01-15 14:17:33 -08:00
parent 9a9e3b629f
commit e090f657bb
3 changed files with 13 additions and 6 deletions

View File

@ -57,7 +57,10 @@ func (c *Component) Compute(ctx context.Context, s Solver, out Fillable) (FS, er
if err != nil { if err != nil {
return fs, err return fs, err
} }
_, err = fs.ReadDir(ctx, "/")
// Force a `Solve()` in case it hasn't been called earlier.
// If the FS is already solved, this is a noop.
_, err = fs.Solve(ctx)
return fs, err return fs, err
} }

View File

@ -105,10 +105,6 @@ func (fs FS) walk(ctx context.Context, p string, fn WalkFunc) error {
type WalkFunc func(string, Stat) error type WalkFunc func(string, Stat) error
func (fs FS) Walk(ctx context.Context, fn WalkFunc) error { func (fs FS) Walk(ctx context.Context, fn WalkFunc) error {
// Lazy solve
if err := (&fs).solve(ctx); err != nil {
return err
}
return fs.walk(ctx, "/", fn) return fs.walk(ctx, "/", fn)
} }

View File

@ -30,6 +30,7 @@ func (s Solver) Scratch() FS {
return s.FS(llb.Scratch()) return s.FS(llb.Scratch())
} }
// Solve will block until the state is solved and returns a Reference.
func (s Solver) Solve(ctx context.Context, st llb.State) (bkgw.Reference, error) { func (s Solver) Solve(ctx context.Context, st llb.State) (bkgw.Reference, error) {
// marshal llb // marshal llb
def, err := st.Marshal(ctx, llb.LinuxAmd64) def, err := st.Marshal(ctx, llb.LinuxAmd64)
@ -37,7 +38,14 @@ func (s Solver) Solve(ctx context.Context, st llb.State) (bkgw.Reference, error)
return nil, err return nil, err
} }
// call solve // call solve
res, err := s.c.Solve(ctx, bkgw.SolveRequest{Definition: def.ToPB()}) res, err := s.c.Solve(ctx, bkgw.SolveRequest{
Definition: def.ToPB(),
// makes Solve() to block until LLB graph is solved. otherwise it will
// return result (that you can for example use for next build) that
// will be evaluated on export or if you access files on it.
Evaluate: true,
})
if err != nil { if err != nil {
return nil, err return nil, err
} }