Skip to content
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

feat: support Nacos v2 as ServiceRegistry (1/n) #703

Merged
merged 75 commits into from
Sep 9, 2024
Merged

Conversation

lyt122
Copy link
Contributor

@lyt122 lyt122 commented Sep 1, 2024

ref #258
It's about start and stop the Nacos

@github-actions github-actions bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Sep 1, 2024
Copy link

codecov bot commented Sep 1, 2024

Codecov Report

Attention: Patch coverage is 81.57895% with 35 lines in your changes missing coverage. Please review.

Project coverage is 88.06%. Comparing base (7b103a2) to head (d76d0c6).
Report is 11 commits behind head on main.

Files with missing lines Patch % Lines
controller/registries/nacos/v1/config.go 83.33% 13 Missing and 4 partials ⚠️
controller/registries/nacos/v2/config.go 70.83% 12 Missing and 2 partials ⚠️
controller/registries/nacos/config.go 90.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #703      +/-   ##
==========================================
- Coverage   88.47%   88.06%   -0.41%     
==========================================
  Files         121      128       +7     
  Lines        5995     6378     +383     
==========================================
+ Hits         5304     5617     +313     
- Misses        492      548      +56     
- Partials      199      213      +14     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.


option go_package = "mosn.io/htnn/types/registries/nacos/v2";

message Config {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How many differences between Nacos v1 & v2? If the Nacos v2 shares the most options with the v1, we can just add a new field to indicate if v2 or v1 is used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are not many differences between Nacos v1 and v2 in terms of configuration options. Both versions share the same fields

)

func init() {
registry.AddRegistryFactory(nacos.Name, func(store registry.ServiceEntryStore, om metav1.ObjectMeta) (registry.Registry, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the Nacos v1 & v2 uses the same Nacos registry, we should not register a new registry, but add the v2 support in the existing Nacos implementation.

@lyt122 lyt122 marked this pull request as draft September 3, 2024 14:31
fix license

update nacos docs

add nacos param

add nacos param

add nacos param

add nacos param

add nacos param

add nacos param

fix license

fix license

update nacos docs

add nacos param

add nacos param

add nacos param

add nacos param

add nacos param

feat: support Nacos v2 as ServiceRegistry
@lyt122 lyt122 marked this pull request as ready for review September 4, 2024 09:12
@lyt122
Copy link
Contributor Author

lyt122 commented Sep 4, 2024

@spacewander

}
if len(config.Groups) == 0 {
config.Groups = []string{"DEFAULT_GROUP"}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code above is almost copied from the config.go. Could we share as much as possible?
For example, we can construct the project like this:

nacos/
   client/
     v1/
     v2/

the package v1 implements v1 client, and v2 implements v2 client. The client is an interface that provides the methods which are different in v1/v2. The common part will be outside of the client interface.

Copy link
Contributor Author

@lyt122 lyt122 Sep 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of nacos api is different.
v1 use "github.com/nacos-group/nacos-sdk-go"
v2 use "github.com/nacos-group/nacos-sdk-go/v2"
So the shared code is little.

Copy link
Member

@spacewander spacewander Sep 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lyt122
Thanks for your explanation. What a pity!

What about writing code like this:

func (reg *Nacos) Start(c registrytype.RegistryConfig) error {
	config := c.(*nacos.Config)
	reg.version = config.Version
        // this method returns a client interface
	client, err := reg.newClient(config)
	if err != nil {
		return err
	}
        // call client's fetchAllServices inside
	fetchedServices, err := reg.fetchAllServices(client)
	if err != nil {
		return fmt.Errorf("fetch all services error: %v", err)
	}
	reg.client = client

	for key := range fetchedServices {
                 // // call client's subscribe inside
		err = reg.subscribe(key.GroupName, key.ServiceName)
		if err != nil {
			reg.logger.Errorf("failed to subscribe service, err: %v, service: %v", err, key)
			// the service will be resubscribed after refresh interval
			delete(fetchedServices, key)
		}
	}

	reg.watchingServices = fetchedServices

	dur := 30 * time.Second
	refreshInteval := config.GetServiceRefreshInterval()
	if refreshInteval != nil {
		dur = refreshInteval.AsDuration()
	}

Copy link
Contributor Author

@lyt122 lyt122 Sep 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spacewander
The subscribe function need the getSubscribeCallback function, which need store in Nacos to update serviceEntry.
And other params also is needed, such as stopped, logger.
Should I write like this

subscribe(groupName string, serviceName string, stopped atomic.Bool, logger log.RegistryLogger, store registry.ServiceEntryStore)

or add these params in Client struct?like this

type nacosClient struct {
    Groups    []string
    Namespace string
    namingClient *Client
    logger log.RegistryLogger
    stopped atomic.Bool
    store   registry.ServiceEntryStore
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about passing the result of getSubscribeCallback? In this way only one param is needed.
We can define our own model.SubscribeService, which is the common part between Nacos v1 & v2's models. Then we can add an adapter to wrap the result of getSubscribeCallback.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

v1's callback use model.SubscribeService

type SubscribeService struct {
	ClusterName string            `json:"clusterName"`
	Enable      bool              `json:"enable"`
	InstanceId  string            `json:"instanceId"`
	Ip          string            `json:"ip"`
	Metadata    map[string]string `json:"metadata"`
	Port        uint64            `json:"port"`
	ServiceName string            `json:"serviceName"`
	Valid       bool              `json:"valid"`
	Weight      float64           `json:"weight"`
	Healthy     bool              `json:"healthy"`
}

but v2's callback use model.Instance

type Instance struct {
    InstanceId                string            `json:"instanceId"`
    Ip                        string            `json:"ip"`
    Port                      uint64            `json:"port"`
    Weight                    float64           `json:"weight"`
    Healthy                   bool              `json:"healthy"`
    Enable                    bool              `json:"enabled"`
    Ephemeral                 bool              `json:"ephemeral"`
    ClusterName               string            `json:"clusterName"`
    ServiceName               string            `json:"serviceName"`
    Metadata                  map[string]string `json:"metadata"`
    InstanceHeartBeatInterval int               `json:"instanceHeartBeatInterval"`
    IpDeleteTimeout           int               `json:"ipDeleteTimeout"`
    InstanceHeartBeatTimeOut  int               `json:"instanceHeartBeatTimeOut"`
}

we can't define the common part

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only use Ip, Port and Metadata in getSubscribeCallback. These fields exits both in v1 and v2, so it is possible to define the common part

@github-actions github-actions bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Sep 8, 2024
@lyt122
Copy link
Contributor Author

lyt122 commented Sep 8, 2024

@spacewander

reg.version = config.Version
if reg.version == "v1" {
cli, err := v1.NewClient(config)
if err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can move the part after if err != nil { outside the current block.

reg.client = cli
} else if reg.version == "v2" {
cli, err := v2.NewClient(config)
if err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

if err != nil {
return err
if reg.version == "v1" {
cli, err := v1.NewClient(config)
Copy link
Member

@spacewander spacewander Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto. We can wrap the version handling in a new method

}

func (c *NacosClient) unsubscribe(groupName string, serviceName string, callback func(services []model.SubscribeService, err error)) error {
err := c.client.Subscribe(&vo.SubscribeParam{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong method?

@lyt122
Copy link
Contributor Author

lyt122 commented Sep 9, 2024

@spacewander

@spacewander spacewander changed the title feat: support Nacos v2 as ServiceRegistry feat: support Nacos v2 as ServiceRegistry (1/n) Sep 9, 2024
@spacewander spacewander merged commit f3054d2 into mosn:main Sep 9, 2024
14 checks passed
@spacewander
Copy link
Member

@lyt122
Thanks for your contribution!

BTW, you can use main branch to sync the upstream, and use a separate branch to develop feature. Therefore, previous commits won't be in the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants