Very cool!
The fan-in part of the example I linked is what makes dagger automatically build each container in parallel, but there's certainly other ways of parallelizing.
The pattern in your original snippet is pretty common in dagger pipelines actually because you might have some common part of a container that you'll use with some modification throughout your pipelines. So by defining it once you simplify your code but also improve the performance of all of the pipelines because they're reusing a common resource. For example, I might define a base container with a set of dependencies installed, and then refer to that base from my test, lint, and build pipelines where they may modify the container further and then run commands.
Thinking about what you're saying for retrying, depending on what the actual limitation is, you may not necessarily need a new variable. Like if you just need c to successfully build, it might just look something like
c := dag.Container().From("alpine"). (all the extra business logic here)
success := false
while !success {
c, err := c.Sync(ctx)
if err == nil {
success = true
}
}