Repository: go-kratos/kratos
Pull request #2235 (2022-07-25 07:05:37)

fix: zookeeper add auto re-register
<!--
🎉 Thanks for sending a pull request to Kratos! Here are some tips for you:

1. If this is your first time contributing to Kratos, please read our contribution guide: https://go-kratos.dev/en/docs/community/contribution/
2. Ensure you have added or ran the appropriate tests and lint for your PR, please use `make lint` and `make test` before filing your PR, use `make clean` to tidy your go mod.
3. If the PR is unfinished, you may need to mark it as a WIP(Work In Progress) PR or draft PR
4. Please use a semantic commits format title, such as `<type>[optional scope]: <description>`, see: https://go-kratos.dev/docs/community/contribution#type
5. at the same time, please note that similar work should be submitted in one PR as far as possible to reduce the workload of reviewers. Do not split a work into multiple PR unless it should.
-->

<!--
🎉 感谢您向 Kratos 发送 PR 请求！以下是一些提示：
如果这是你第一次为 Kratos 贡献，请阅读我们的贡献指南：https://go-kratos.dev/en/docs/community/contribution/
2、确保您已经为您的 PR 添加或运行了适当的测试和lint，请在提交PR之前使用“make lint”和“make test”，使用“make clean”整理您的 go.mod。
3、如果请购单未完成，您可能需要将其标记为 WIP（在制品）PR 或 draft PR
4、请使用语义提交格式标题，如“<类型>[可选范围]：<说明>`，请参阅：https://go-kratos.dev/docs/community/contribution#type
5. 同时请注意，同类的工作请尽量在一个PR中提交，以减轻 review 者的工作负担，不要把一项工作拆分成很多个PR，除非它应该这样做。
-->

<!--
-->

#### Description (what this PR does / why we need it):
<!--
* The description should include the motivation for this PR or contrast this with previous behavior
-->
The current registrar with zookeeper will re-connected when bad connection and so on.
But the data node info will not re-register. It makes no sense.
This pr provides reRegister function with a goroutine support that app can auto recovery and re-register with registrar.

#### Which issue(s) this PR fixes (resolves / be part of):
<!--
* Automatically closes linked issue when PR is merged.
* If your PR is not fully resolved the issue, please use `part of #<issue number>` instead.

Usage: `fixes/resolves #<issue number>`, or `fixes/resolves (paste link of issue)`.
-->


#### Other special notes for the reviewers:
<!--
* Somethings that need extra attention for the reviewers
* Some additional notes, TODO list, etc.
-->


codecov-commenter: # [Codecov](https://codecov.io/gh/go-kratos/kratos/pull/2235?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) Report
> Merging [#2235](https://codecov.io/gh/go-kratos/kratos/pull/2235?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) (7455148) into [main](https://codecov.io/gh/go-kratos/kratos/commit/14cfd65b62751fd07006a0d43b40c03f9ca516d1?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) (14cfd65) will **not change** coverage.
> The diff coverage is `n/a`.

```diff
@@           Coverage Diff           @@
##             main    #2235   +/-   ##
=======================================
  Coverage   85.73%   85.73%           
=======================================
  Files          86       86           
  Lines        3758     3758           
=======================================
  Hits         3222     3222           
  Misses        369      369           
  Partials      167      167           
```



------

[Continue to review full report at Codecov](https://codecov.io/gh/go-kratos/kratos/pull/2235?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/go-kratos/kratos/pull/2235?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos). Last update [14cfd65...7455148](https://codecov.io/gh/go-kratos/kratos/pull/2235?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos).


Patch:
diff --git a/contrib/config/polaris/config.go b/contrib/config/polaris/config.go
index f5d52d18..c3c39ece 100644
--- a/contrib/config/polaris/config.go
+++ b/contrib/config/polaris/config.go
@@ -43,11 +43,11 @@ func WithFileName(fileName string) Option {
 }
 
 type source struct {
-	client  *polaris.ConfigAPI
+	client  polaris.ConfigAPI
 	options *options
 }
 
-func New(client *polaris.ConfigAPI, opts ...Option) (config.Source, error) {
+func New(client polaris.ConfigAPI, opts ...Option) (config.Source, error) {
 	options := &options{
 		namespace: "default",
 		fileGroup: "",
@@ -74,12 +74,7 @@ func New(client *polaris.ConfigAPI, opts ...Option) (config.Source, error) {
 
 // Load return the config values
 func (s *source) Load() ([]*config.KeyValue, error) {
-	configAPI, err := polaris.NewConfigAPI()
-	if err != nil {
-		return nil, err
-	}
-
-	configFile, err := configAPI.GetConfigFile(s.options.namespace, s.options.fileGroup, s.options.fileName)
+	configFile, err := s.client.GetConfigFile(s.options.namespace, s.options.fileGroup, s.options.fileName)
 	if err != nil {
 		fmt.Println("fail to get config.", err)
 		return nil, err
diff --git a/contrib/registry/zookeeper/register.go b/contrib/registry/zookeeper/register.go
index 2aedc198..a9de43c8 100644
--- a/contrib/registry/zookeeper/register.go
+++ b/contrib/registry/zookeeper/register.go
@@ -3,6 +3,7 @@ package zookeeper
 import (
 	"context"
 	"path"
+	"time"
 
 	"github.com/go-zookeeper/zk"
 	"golang.org/x/sync/singleflight"
@@ -77,6 +78,7 @@ func (r *Registry) Register(ctx context.Context, service *registry.ServiceInstan
 	if err = r.ensureName(servicePath, data, zk.FlagEphemeral); err != nil {
 		return err
 	}
+	go r.reRegister(servicePath, data)
 	return nil
 }
 
@@ -150,3 +152,21 @@ func (r *Registry) ensureName(path string, data []byte, flags int32) error {
 	}
 	return nil
 }
+
+// reRegister re-register data node info when bad connection recovered
+func (r *Registry) reRegister(path string, data []byte) {
+	sessionID := r.conn.SessionID()
+	ticker := time.NewTicker(time.Second)
+	defer ticker.Stop()
+	for range ticker.C {
+		cur := r.conn.SessionID()
+		// sessionID changed
+		if cur > 0 && sessionID != cur {
+			// re-ensureName
+			if err := r.ensureName(path, data, zk.FlagEphemeral); err != nil {
+				return
+			}
+			sessionID = cur
+		}
+	}
+}


Test patch:
diff --git a/contrib/config/polaris/config_test.go b/contrib/config/polaris/config_test.go
index 6dfaeb3f..fc864526 100644
--- a/contrib/config/polaris/config_test.go
+++ b/contrib/config/polaris/config_test.go
@@ -213,7 +213,7 @@ func TestConfig(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	config, err := New(&configAPI, WithNamespace(namespace), WithFileGroup(fileGroup), WithFileName(name))
+	config, err := New(configAPI, WithNamespace(namespace), WithFileGroup(fileGroup), WithFileName(name))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -285,7 +285,7 @@ func TestExtToFormat(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	config, err := New(&configAPI, WithNamespace(namespace), WithFileGroup(fileGroup), WithFileName(name))
+	config, err := New(configAPI, WithNamespace(namespace), WithFileGroup(fileGroup), WithFileName(name))
 	if err != nil {
 		t.Fatal(err)
 	}