xxs588 commented on code in PR #3270:
URL: https://github.com/apache/dubbo-go/pull/3270#discussion_r2988441195


##########
registry/directory/directory.go:
##########
@@ -187,26 +182,49 @@ func (dir *RegistryDirectory) Subscribe(url *common.URL) 
error {
                timeout, _ = time.ParseDuration(constant.DefaultRegTimeout)
        }
 
-       done := make(chan struct{})
+       serviceKey := url.Key()
+       // Registration is bounded by registry timeout (default 5s).
+       // On timeout, we return immediately and skip starting subscribe 
goroutine.
+       if err := dir.registerConsumerWithTimeout(url, timeout, serviceKey); 
err != nil {
+               return err
+       }
 
        go func() {
-               urlToReg := getConsumerUrlToRegistry(url)
-               err := dir.registry.Register(urlToReg)
-               if err != nil {
-                       logger.Errorf("consumer service %v register registry %v 
error, error message is %v",
-                               url.String(), dir.registry.GetURL().String(), 
err)
+               if err := dir.registry.Subscribe(url, dir); err != nil {
+                       logger.Error("registry.Subscribe(url:%v, dir:%v) = 
error:%v", url, dir, err)
                }
+       }()
 
-               close(done)
+       logger.Infof("register completed successfully for service: %s", 
serviceKey)
+       return nil
+}
+
+func (dir *RegistryDirectory) registerConsumerWithTimeout(url *common.URL, 
timeout time.Duration, serviceKey string) error {
+       registerErrCh := make(chan error, 1)
+       go func() {
+               urlToReg := getConsumerUrlToRegistry(url.Clone())
+               registerErrCh <- dir.registry.Register(urlToReg)
        }()
 
+       timer := time.NewTimer(timeout)
+       defer timer.Stop()
+
        select {
-       case <-done:
-               logger.Infof("register completed successfully for service: %s", 
url.Key())
+       case err := <-registerErrCh:
+               if err != nil {
+                       registryURL := dir.registry.GetURL()
+                       registryURLString := ""
+                       if registryURL != nil {
+                               registryURLString = registryURL.String()
+                       }
+                       logger.Errorf("consumer service %v register registry %v 
error, error message is %v",
+                               url.String(), registryURLString, err)
+                       return err
+               }
                return nil
-       case <-time.After(timeout):
-               logger.Errorf("register timed out for service: %s", url.Key())
-               return fmt.Errorf("register timed out for service: %s", 
url.Key())
+       case <-timer.C:

Review Comment:
   感谢 ,已修改成 registerConsumerWithTimeout() 超时返回后,如果 Register 迟到成功,则执行 UnRegister 
回滚
   逻辑详见图片
   <img width="1112" height="296" alt="图片" 
src="https://github.com/user-attachments/assets/2e35b39c-b5dd-45a2-abc6-bc70fe7491fc";
 />
   
   <img width="1110" height="452" alt="图片" 
src="https://github.com/user-attachments/assets/247e75e4-51df-4b7e-ac5f-d8a7836bbde3";
 />
   
如果`Subscribe`超时返回错误了但是后面goroutine可能没那么快结束,所以再起一个goroutine等待结果,如果`Register`失败了就不用补偿直接return
 ,如果成功了说明出现 调用方收到超时失败,但实际上已经注册成功的状态,然后就再补偿 回滚把迟到成功的注册注销掉,如果回滚失败也补上日志方便定位



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to