chore: concurrent image build with context cancellation#4760
chore: concurrent image build with context cancellation#4760mergify[bot] merged 25 commits intoaws:mainlinefrom
Conversation
|
🍕 Here are the new binary sizes!
|
Codecov Report
@@ Coverage Diff @@
## mainline #4760 +/- ##
============================================
- Coverage 69.91% 69.91% -0.01%
============================================
Files 284 284
Lines 40694 40795 +101
Branches 272 272
============================================
+ Hits 28450 28520 +70
- Misses 10869 10892 +23
- Partials 1375 1383 +8
... and 5 files with indirect coverage changes Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
paragbhingre
left a comment
There was a problem hiding this comment.
This is really cool 😎
| numLinesForBuildAndPush = -1 | ||
| } | ||
| // create a LabeledTermPrinter for rendering build and push output. | ||
| ltp := syncbuffer.NewLabeledTermPrinter(os.Stderr, labeledBuffers, syncbuffer.WithNumLines(numLinesForBuildAndPush), syncbuffer.WithPadding(paddingForBuildAndPush)) |
There was a problem hiding this comment.
What do you think of this
// In cli/deploy/workload.go
type termPrinter interface { // And use make gen-mocks to generate a mock for unit testing
IsDone() bool
Print() error
}
type workloadDeployer struct {
newTermPrinter (fw FileWriter, bufs []*LabeledSyncBuffer, opts ...LabeledTermPrinterOption) termPrinter
}
func newWorkloadDeployer(in *WorkloadDeployerInput) (*workloadDeployer, error) {
return &workloadDeployer{
newTermPrinter: syncbuffer.NewLabeledTermPrinter,
}
}
}
func (d *workloadDeployer) uploadContainerImages(out *UploadArtifactsOutput) error {
//...
ltp := d.newTermPrinter(os.Stderr, labeledBuffers, syncbuffer.WithNumLines(numLinesForBuildAndPush), syncbuffer.WithPadding(paddingForBuildAndPush))
//...
}
// In cli/deploy/workload_test.go
type deployMocks struct {
//...
mockTermPrinter *mocks.mockTermPrinter
}
func TestWorkloadDeployer_UploadArtifacts(t *testing.T) {
m := &deployMocks{
mockTermPrinter: mocks.NewMockTermPrinter(ctril)
}
m.mockTermPrinter.Expect().Print().Return(nil)
wkldDeployer := &workloadDeployer{
newTermPrinter: func(fw FileWriter, bufs []*LabeledSyncBuffer, opts ...LabeledTermPrinterOption) termPrinter {
return m.mockTermPrinter
}
}
}The reason why it is so hard to write unit test for UploadArtifacts is that the constructor for term printer is currently called within uploadContainerImages(). However, in order to properly test UploadArtifacts, we need to sub the labeled term printer with a mock. The solution is to mock the constructor function call - in our case newTermPrinter.
remove same method on CmdClient that even reduce code changes
590c6c9 to
272650c
Compare
| envSess: envSession, | ||
| store: store, | ||
| envConfig: envConfig, | ||
| labeledTermPrinter: func(fw syncbuffer.FileWriter, bufs []*syncbuffer.LabeledSyncBuffer, opts ...syncbuffer.LabeledTermPrinterOption) labeledTermPrinter { |
There was a problem hiding this comment.
nit:
| labeledTermPrinter: func(fw syncbuffer.FileWriter, bufs []*syncbuffer.LabeledSyncBuffer, opts ...syncbuffer.LabeledTermPrinterOption) labeledTermPrinter { | |
| labeledTermPrinter: syncbuffer.NewLabeledTermPrinter, |
There was a problem hiding this comment.
This will be aIncompatibleAssign 🤔 . if I directly use syncbuffer.NewLabeledTermPrinter
because the the function signature of the labeledTermPrinter field in workloadDeployer struct does not match the signature of syncbuffer.NewLabeledTermPrinter function.
add logic to termprinter for removing the buffer once they are done
efekarakus
left a comment
There was a problem hiding this comment.
with a small tiny test adjustment request
| if err != nil { | ||
| return fmt.Errorf("build and push the image for %q container: %w", name, err) | ||
| } | ||
| digestsMu.Lock() |
There was a problem hiding this comment.
| digestsMu.Lock() | |
| digestsMu.Lock() | |
| defer digestsMu.Unlock() |
There was a problem hiding this comment.
is it good to unlock the map before return nil? I mean if I use defer then i will unlock after return is executed.
dannyrandall
left a comment
There was a problem hiding this comment.
looks great! good work
| if ltp.IsDone() { | ||
| return nil | ||
| } | ||
| time.Sleep(pollIntervalForBuildAndPush) |
There was a problem hiding this comment.
| time.Sleep(pollIntervalForBuildAndPush) | |
| select { | |
| case <-ctx.Done(): | |
| return nil | |
| case <-time.After(pollIntervalForBuildAndPush): | |
| // loop again | |
| } |
so this function stops if ctx is cancelled!
Finally with this PR we can build container images in parallel.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the Apache 2.0 License.