From 614efda62f5b6afde2869b2085e996ee148ad67b Mon Sep 17 00:00:00 2001 From: Aidan Steele Date: Sun, 12 May 2019 15:45:15 +1000 Subject: [PATCH] Don't close channels (or range over them) when done. This is groundwork for #20 and #23 --- cmd/down.go | 21 ++++++++++++++++++--- cmd/execute.go | 12 ++++++++++-- cmd/package.go | 12 ++++++++++-- cmd/up.go | 18 ++++++++++++++---- pkg/stackit/down.go | 14 ++------------ pkg/stackit/up.go | 3 --- pkg/stackit/up_test.go | 5 +++-- 7 files changed, 57 insertions(+), 28 deletions(-) diff --git a/cmd/down.go b/cmd/down.go index c2ce303..7de8157 100644 --- a/cmd/down.go +++ b/cmd/down.go @@ -38,10 +38,25 @@ var downCmd = &cobra.Command{ sess := awsSession(profile, region) sit := stackit.NewStackit(cloudformation.New(sess), sts.New(sess)) - go sit.Down(context.Background(), stackName, events) - for tailEvent := range events { - printer.PrintTailEvent(tailEvent) + ctx := context.Background() + printerCtx, printerCancel := context.WithCancel(ctx) + defer printerCancel() + + go func() { + for { + select { + case <-printerCtx.Done(): + return + case tailEvent := <-events: + printer.PrintTailEvent(tailEvent) + } + } + }() + + err := sit.Down(ctx, stackName, events) + if err != nil { + panic(err) } }, } diff --git a/cmd/execute.go b/cmd/execute.go index 3aae81c..51613dc 100644 --- a/cmd/execute.go +++ b/cmd/execute.go @@ -31,9 +31,17 @@ func executeChangeSet(ctx context.Context, region, profile, stackName, changeSet events := make(chan stackit.TailStackEvent) printer := stackit.NewTailPrinterWithOptions(true, true, writer) + printerCtx, printerCancel := context.WithCancel(ctx) + defer printerCancel() + go func() { - for event := range events { - printer.PrintTailEvent(event) + for { + select { + case <-printerCtx.Done(): + return + case tailEvent := <-events: + printer.PrintTailEvent(tailEvent) + } } }() diff --git a/cmd/package.go b/cmd/package.go index 9a7a98c..96bbd4e 100644 --- a/cmd/package.go +++ b/cmd/package.go @@ -48,9 +48,17 @@ func packageTemplate(ctx context.Context, region, profile, stackName, templatePa events := make(chan stackit.TailStackEvent) printer := stackit.NewTailPrinterWithOptions(true, true, writer) + printerCtx, printerCancel := context.WithCancel(ctx) + defer printerCancel() + go func() { - for event := range events { - printer.PrintTailEvent(event) + for { + select { + case <-printerCtx.Done(): + return + case tailEvent := <-events: + printer.PrintTailEvent(tailEvent) + } } }() diff --git a/cmd/up.go b/cmd/up.go index c8b566f..f6ce8f0 100644 --- a/cmd/up.go +++ b/cmd/up.go @@ -69,13 +69,23 @@ var upCmd = &cobra.Command{ sess := awsSession(profile, region) sit := stackit.NewStackit(cloudformation.New(sess), sts.New(sess)) + ctx := context.Background() + + printerCtx, printerCancel := context.WithCancel(ctx) + defer printerCancel() + go func() { - for tailEvent := range events { - printer.PrintTailEvent(tailEvent) + for { + select { + case <-printerCtx.Done(): + return + case tailEvent := <-events: + printer.PrintTailEvent(tailEvent) + } } }() - prepared, err := sit.Prepare(context.Background(), parsed, events) + prepared, err := sit.Prepare(ctx, parsed, events) if err != nil { panic(err) } @@ -84,7 +94,7 @@ var upCmd = &cobra.Command{ return // no-op change set } - err = sit.Execute(context.Background(), *prepared.Output.StackId, *prepared.Output.Id, events) + err = sit.Execute(ctx, *prepared.Output.StackId, *prepared.Output.Id, events) if err != nil { panic(err) } diff --git a/pkg/stackit/down.go b/pkg/stackit/down.go index a1ca5ba..22d2bfd 100644 --- a/pkg/stackit/down.go +++ b/pkg/stackit/down.go @@ -18,7 +18,6 @@ func (s *Stackit) Down(ctx context.Context, stackName string, events chan<- Tail } _, err = s.api.DeleteStack(input) if err != nil { - close(events) return err } @@ -26,7 +25,6 @@ func (s *Stackit) Down(ctx context.Context, stackName string, events chan<- Tail events <- event }) if err != nil { - close(events) return err } @@ -35,13 +33,11 @@ func (s *Stackit) Down(ctx context.Context, stackName string, events chan<- Tail input.ClientRequestToken = &token input.RetainResources, err = s.resourcesToBeRetainedDuringDelete(*stack.StackId, events) if err != nil { - close(events) return errors.Wrap(err, "determining resources to be kept") } _, err = s.api.DeleteStack(input) if err != nil { - close(events) return errors.Wrap(err, "deleting stack") } @@ -49,18 +45,16 @@ func (s *Stackit) Down(ctx context.Context, stackName string, events chan<- Tail events <- event }) if err != nil { - close(events) return errors.Wrap(err, "deleting stack") } } } - close(events) return nil } func (s *Stackit) resourcesToBeRetainedDuringDelete(stackName string, events chan<- TailStackEvent) ([]*string, error) { - names := []*string{} + var names []*string err := s.api.ListStackResourcesPages(&cloudformation.ListStackResourcesInput{StackName: &stackName}, func(page *cloudformation.ListStackResourcesOutput, lastPage bool) bool { for _, resource := range page.StackResourceSummaries { @@ -70,10 +64,6 @@ func (s *Stackit) resourcesToBeRetainedDuringDelete(stackName string, events cha } return !lastPage }) - if err != nil { - close(events) - return nil, err - } - return names, nil + return names, errors.Wrap(err, "listing stack resources") } diff --git a/pkg/stackit/up.go b/pkg/stackit/up.go index 8279ff2..60d0b26 100644 --- a/pkg/stackit/up.go +++ b/pkg/stackit/up.go @@ -73,7 +73,6 @@ func (s *Stackit) ensureStackReady(ctx context.Context, stackName string, events token := generateToken() _, err := s.api.DeleteStack(&cloudformation.DeleteStackInput{StackName: &stackId, ClientRequestToken: &token}) if err != nil { - close(events) return err } @@ -225,7 +224,6 @@ func (s *Stackit) Execute(ctx context.Context, stackId, changeSetId string, even }) if err != nil { - close(events) return errors.Wrap(err, "executing change set") } @@ -233,6 +231,5 @@ func (s *Stackit) Execute(ctx context.Context, stackId, changeSetId string, even events <- event }) - close(events) return nil } diff --git a/pkg/stackit/up_test.go b/pkg/stackit/up_test.go index 41c26c1..e6d10dd 100644 --- a/pkg/stackit/up_test.go +++ b/pkg/stackit/up_test.go @@ -1,6 +1,7 @@ package stackit import ( + "context" "errors" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" @@ -45,7 +46,7 @@ func TestServiceRoleArnCanBeName(t *testing.T) { } ch := make(chan TailStackEvent) - _, err := s.Prepare(input, ch) + _, err := s.Prepare(context.Background(), input, ch) assert.EqualError(t, err, "creating change set: done") } @@ -83,6 +84,6 @@ func TestServiceRoleArnDoesntTriggerStsCall(t *testing.T) { } ch := make(chan TailStackEvent) - _, err := s.Prepare(input, ch) + _, err := s.Prepare(context.Background(), input, ch) assert.EqualError(t, err, "creating change set: done") }