-
Notifications
You must be signed in to change notification settings - Fork 118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Thread safety #688
Thread safety #688
Conversation
… of AliyunClients could lead to data race issues. Migrate datasources to the new AliyunClient.
… the new AliyunClient.
…ources to the new AliyunClient.
…cloud_db_instance resources to the new AliyunClient.
…he new AliyunClient.
…resources to the new AliyunClient.
…e new AliyunClient.
…ess_lifecyclehook resources to the new AliyunClient.
…oup, alicloud_ess_scalingrule and alicloud_ess_schedule resources to the new AliyunClient.
…_trigger resources to the new AliyunClient.
…ead-safe AliyunClient.
…d_log_store and alicloud_log_store_index resource to the new AliyunClient.
…ce to the new AliyunClient.
…nd alicloud_ots_table resource to the new AliyunClient.
…cloud_pvtz_zone_record resource to the new AliyunClient.
…_ram_group, alicloud_ram_group_membership and alicloud_ram_group_policy_attachment to the thread-safe AliyunClient.
…icloud_vpn_gateway to the thread-safe AliyunClient.
…the NewClient methods into aliyunclient to do that). Clean some code.
# Conflicts: # alicloud/common.go # alicloud/config.go # alicloud/data_source_alicloud_zones.go # alicloud/extension_ess.go # alicloud/resource_alicloud_cs_kubernetes.go # alicloud/resource_alicloud_db_connection.go # alicloud/resource_alicloud_db_connection_test.go # alicloud/resource_alicloud_kvstore_instance.go # alicloud/service_alicloud_cen.go
# Conflicts: # alicloud/common.go # alicloud/config.go # alicloud/data_source_alicloud_zones.go # alicloud/extension_ess.go # alicloud/resource_alicloud_cs_kubernetes.go # alicloud/resource_alicloud_db_connection.go # alicloud/resource_alicloud_db_connection_test.go # alicloud/resource_alicloud_kvstore_instance.go # alicloud/service_alicloud_cen.go
@@ -0,0 +1,726 @@ | |||
package aliyunclient |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think package name client
is not better because this package does not just contain client.
In addition, I think just use client.go
is ok.
"regexp" | ||
|
||
"sync" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please run make fmt
before next submitting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strange, I do it again but it doesn't change any of my files. What happen if you do it on your computer?
if identity.AccountId == "" { | ||
return "", fmt.Errorf("caller identity doesn't contain any AccountId") | ||
} | ||
log.Printf("[DEBUG] account_id retrieved with success.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think line 629 can be removed and if it is not success, it will return an error.
|
||
func (client *AliyunClient) getCallerIdentity() (*sts.GetCallerIdentityResponse, error) { | ||
args := sts.CreateGetCallerIdentityRequest() | ||
args.Scheme = "https" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think args.Scheme = string(Https)
will be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately not possible because the Https constant is defined outside of the package.
|
||
args := rds.CreateDescribeDBInstancesRequest() | ||
|
||
args.RegionId = getRegionId(d, meta) | ||
args.RegionId = meta.(*aliyunclient.AliyunClient).RegionId |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think using args.RegionId = client.RegionId
will be better.
@@ -145,14 +147,17 @@ func resourceAlicloudCSApplicationCreate(d *schema.ResourceData, meta interface{ | |||
} | |||
invoker := NewInvoker() | |||
if err := invoker.Run(func() error { | |||
return conn.CreateProject(args) | |||
_, err := csService.RunSafelyWithCsProjectClientByClusterName(clusterName, func(csProjectClient *cs.ProjectClient) (interface{}, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why line 150 is csService.RunSafelyWithCsProjectClientByClusterName
not client.RunSafelyWithCsProjectClientByClusterName
client.RunSafelyWithOssClient(func(ossClient *oss.Client) (interface{}, error) { | ||
log.Printf("[DEBUG] OSS bucket create: %#v, using endpoint: %#v", bucket, ossClient.Config.Endpoint) | ||
return nil, nil | ||
}) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove line 226-229.
alicloud/service_alicloud_cen.go
Outdated
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" | ||
"github.com/aliyun/alibaba-cloud-sdk-go/services/cbn" | ||
) | ||
|
||
type CenService struct { | ||
client *aliyunclient.AliyunClient |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think line 14 just using *aliyunclient.AliyunClient
is ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree, the semantic changes when you remove "client": in the current implementation a service uses the client, but in what you propose the service extends the client.
Although it is slightly more verbose to write "myService.client.SomeFunction" instead of "myService.SomeFunction", it is easier to read because the reader can immediately understand that the function come from the client, not the service.
It's like the Composition over inheritance principle.
|
||
args := vpc.CreateDescribeEipAddressesRequest() | ||
args.RegionId = string(getRegion(d, meta)) | ||
args.RegionId = string(meta.(*aliyunclient.AliyunClient).Region) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think line 90 uses args.RegionId =client.RegionId
will be better.
}, nil | ||
} | ||
|
||
func (client *AliyunClient) RunSafelyWithEcsClient(do func(*ecs.Client) (interface{}, error)) (interface{}, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR aims to solve GO SDK thread-unsafe problem. I think the prefix RunSafelyWith
is redundant and it can be removed to simplify the client definition. If you want to stress thread-safe, adding some annotations is good choice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I propose to still keep "With" like "WithSomeClient", if not it would look like a weird getter.
…vice.GetContainerClusterAndCertsByName(clusterName) followed by client.RunSafelyWithCsProjectClient().
# Conflicts: # alicloud/common.go # alicloud/config.go # alicloud/resource_alicloud_instance.go # alicloud/resource_alicloud_key_pair.go # alicloud/resource_alicloud_ram_user_policy_attachment.go
# Conflicts: # alicloud/common.go # alicloud/config.go # alicloud/resource_alicloud_instance.go # alicloud/resource_alicloud_key_pair.go # alicloud/resource_alicloud_ram_user_policy_attachment.go
# Conflicts: # alicloud/resource_alicloud_cen_instance.go # alicloud/resource_alicloud_vroute_entry.go # alicloud/service_alicloud_cen.go
# Conflicts: # alicloud/resource_alicloud_cen_instance.go # alicloud/resource_alicloud_vroute_entry.go # alicloud/service_alicloud_cen.go
# Conflicts: # alicloud/resource_alicloud_ess_scalingconfiguration.go # alicloud/resource_alicloud_router_interface.go # alicloud/resource_alicloud_security_group.go # alicloud/service_alicloud_vpc.go
# Conflicts: # alicloud/resource_alicloud_ess_scalingconfiguration.go # alicloud/resource_alicloud_router_interface.go # alicloud/resource_alicloud_security_group.go # alicloud/service_alicloud_vpc.go
The goal of this pull request is to protect alicloud provider from the "thread-unsafety" of the underlying Go SDK. Because Terraform is creating resources in parallel (when possible), it randomly crashes with a panic error when a data race issue is occurring inside the Go SDK, because the later is NOT thread safe.
This pull request contains the following modifications:
service_*.go
cannot be defined forAliyunClient
anymore because they are now located in a different package than AliyunClient, a new struct has been created for each of them. For example calling the functionDescribeAvailableResources
located inalicloud/service_alicloud_ecs.go
become:All the acceptance tests have been executed in Frankfurt (eu-central-1). All of them successfully pass beside:
These tests were already failing for the same reasons before the changes included in this pull request.
The following tests have also been executed successfully in Beijing (cn-beijing):