Skip to content

Commit

Permalink
fix(cloudmeta): fixes handling of context cancellation.
Browse files Browse the repository at this point in the history
This fixes the issue when context that was passed to GetInstanceMetadata is
canceled before any of provider's functions returned.
  • Loading branch information
VAveryanov8 committed Dec 18, 2024
1 parent 58ed47c commit cedece2
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 7 deletions.
14 changes: 9 additions & 5 deletions pkg/cloudmeta/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,16 @@ func (cloud *CloudMeta) GetInstanceMetadata(ctx context.Context) (InstanceMetada
// Return the first non error result or wait until all providers return err.
var mErr error
for range len(cloud.providers) {
res := <-results
if res.err != nil {
mErr = multierr.Append(mErr, res.err)
continue
select {
case <-ctx.Done():
return InstanceMetadata{}, ctx.Err()
case res := <-results:
if res.err != nil {
mErr = multierr.Append(mErr, res.err)
continue
}
return res.meta, nil
}
return res.meta, nil
}
return InstanceMetadata{}, mErr
}
Expand Down
30 changes: 28 additions & 2 deletions pkg/cloudmeta/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ func TestGetInstanceMetadata(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
cloudmeta := &CloudMeta{
providers: tc.providers,
providers: tc.providers,
providerTimeout: 1 * time.Second,
}

meta, err := cloudmeta.GetInstanceMetadata(context.Background())
Expand All @@ -101,6 +102,31 @@ func TestGetInstanceMetadata(t *testing.T) {
}
}

func TestGetInstanceMetadataWithCancelledContext(t *testing.T) {
cloudmeta := &CloudMeta{
providers: []CloudMetadataProvider{
newTestProvider(t, "test_provider_1", "x-test-1", 1*time.Second, nil),
},
providerTimeout: 100 * time.Millisecond,
}

ctx, cancel := context.WithCancel(context.Background())
cancel()

meta, err := cloudmeta.GetInstanceMetadata(ctx)
if !errors.Is(err, context.Canceled) {
t.Fatalf("expected context.Canceled, got %v", err)
}

if meta.CloudProvider != "" {
t.Fatalf("meta.CloudProvider should be empty, got %s", meta.CloudProvider)
}

if meta.InstanceType != "" {
t.Fatalf("meta.InstanceType should be empty, got %s", meta.InstanceType)
}
}

func newTestProvider(t *testing.T, providerName, instanceType string, latency time.Duration, err error) *testProvider {
t.Helper()

Expand Down Expand Up @@ -128,5 +154,5 @@ func (tp testProvider) Metadata(ctx context.Context) (InstanceMetadata, error) {
return InstanceMetadata{
CloudProvider: tp.name,
InstanceType: tp.instanceType,
}, nil
}, ctx.Err()
}

0 comments on commit cedece2

Please sign in to comment.