From 90494ebbd5f83ad9e8b3e1b406bddff742e2eb1c Mon Sep 17 00:00:00 2001 From: liuhaoming Date: Mon, 13 Jan 2025 14:49:20 +0800 Subject: [PATCH] fix: the concurrent calling issue --- kcl.mod | 2 +- src/kawesome_generator.go | 28 +++++++++++++++++++--------- src/kawesome_generator_test.go | 2 +- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/kcl.mod b/kcl.mod index 9528e93..682cf85 100644 --- a/kcl.mod +++ b/kcl.mod @@ -1,3 +1,3 @@ [package] name = "kawesome" -version = "0.3.0" +version = "0.3.1" diff --git a/src/kawesome_generator.go b/src/kawesome_generator.go index a5d8b25..e198c17 100644 --- a/src/kawesome_generator.go +++ b/src/kawesome_generator.go @@ -19,18 +19,25 @@ import ( ) func main() { - server.Start(&Kawesome{}) + server.Start(&KawesomeModGenerator{}) } -// Kawesome implements the Kusion Module generator interface. +// KawesomeModGenerator implements the Kusion Module generator interface. +type KawesomeModGenerator struct{} + +// KawesomeCfgContext records the configuration context of Kawesome Module, which can be used for +// the unmarshalling of `devConfig` items and `platformConfig` items. +// +// Note: separating the definitions of `KawesomeModGenerator` and `KawesomeCfgContext` can ensure that +// the call of module generator is stateless, avoiding the issues concurrency. // -// Note that as an example of a Kusion Module, Kawesome consists of two components, one of which +// As an example of a Kusion Module, Kawesome consists of two components, one of which // is a 'Service', which is used to generate a Kubernetes Service resource, and the other is a // 'RandomePassword', which is used to generate a Terraform random_password resource. // // Typically, these two resources are not particularly related, but here they are combined to primarily // illustrate how to develop a Kusion Module. -type Kawesome struct { +type KawesomeCfgContext struct { // Service is for service configs of kawesome module. Service Service `yaml:"service,omitempty" json:"service,omitempty"` @@ -62,7 +69,7 @@ type RandomPassword struct { // Generate implements the generation logic of kawesome module, including a Kubernetes Service and // a Terraform random_password resource. -func (k *Kawesome) Generate(ctx context.Context, request *module.GeneratorRequest) (response *module.GeneratorResponse, err error) { +func (*KawesomeModGenerator) Generate(ctx context.Context, request *module.GeneratorRequest) (response *module.GeneratorResponse, err error) { // Get the module logger with the generator context. logger := log.GetModuleLogger(ctx) logger.Info("Generating resources...") @@ -90,6 +97,9 @@ func (k *Kawesome) Generate(ctx context.Context, request *module.GeneratorReques return nil, errors.New("port should be binded to a service workload") } + // Initiate a new KawesomeCfgContext instance. + k := &KawesomeCfgContext{} + // Get the complete kawesome module configs. if err := k.CompleteConfig(request.DevConfig, request.PlatformConfig); err != nil { logger.Debug("failed to get complete kawesome module configs: %v", err) @@ -127,7 +137,7 @@ func (k *Kawesome) Generate(ctx context.Context, request *module.GeneratorReques } // CompleteConfig completes the kawesome module configs with both devModuleConfig and platformModuleConfig. -func (k *Kawesome) CompleteConfig(devConfig kusionapiv1.Accessory, platformConfig kusionapiv1.GenericConfig) error { +func (k *KawesomeCfgContext) CompleteConfig(devConfig kusionapiv1.Accessory, platformConfig kusionapiv1.GenericConfig) error { // Retrieve the config items the developers are concerned about. if devConfig != nil { devCfgYamlStr, err := yaml.Marshal(devConfig) @@ -160,7 +170,7 @@ func (k *Kawesome) CompleteConfig(devConfig kusionapiv1.Accessory, platformConfi } // ValidateConfig validates the completed kawesome configs are valid or not. -func (k *Kawesome) ValidateConfig() error { +func (k *KawesomeCfgContext) ValidateConfig() error { if k.Service.Port < 1 || k.Service.Port > 65535 { return errors.New("port must be between 1 and 65535") } @@ -184,7 +194,7 @@ func (k *Kawesome) ValidateConfig() error { // // Note that we will use the SDK provided by the kusion module framework to wrap the Kubernetes resource // into Kusion resource. -func (k *Kawesome) GenerateServiceResource(request *module.GeneratorRequest) (*kusionapiv1.Resource, error) { +func (k *KawesomeCfgContext) GenerateServiceResource(request *module.GeneratorRequest) (*kusionapiv1.Resource, error) { // Generate the unique application name with project, stack and app name. appUniqueName := module.UniqueAppName(request.Project, request.Stack, request.App) svcType := v1.ServiceTypeClusterIP @@ -246,7 +256,7 @@ func (k *Kawesome) GenerateServiceResource(request *module.GeneratorRequest) (*k // // Note that we will use the SDK provided by the kusion module framework to wrap the Terraform resource // into Kusion resource. -func (k *Kawesome) GenerateRandomPasswordResource(request *module.GeneratorRequest) (*kusionapiv1.Resource, *kusionapiv1.Patcher, error) { +func (k *KawesomeCfgContext) GenerateRandomPasswordResource(request *module.GeneratorRequest) (*kusionapiv1.Resource, *kusionapiv1.Patcher, error) { // Set the random_password provider config. randomPasswordPvdCfg := module.ProviderConfig{ Source: "hashicorp/random", diff --git a/src/kawesome_generator_test.go b/src/kawesome_generator_test.go index 37bfe92..04c4696 100644 --- a/src/kawesome_generator_test.go +++ b/src/kawesome_generator_test.go @@ -258,7 +258,7 @@ func TestKawesomeModule_Generate(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - o := &Kawesome{} + o := &KawesomeModGenerator{} got, err := o.Generate(context.Background(), tt.args.request) if (err != nil) != tt.wantErr { t.Errorf("Generate() error = %v, wantErr %v", err, tt.wantErr)