Similarityoung commented on code in PR #994:
URL: https://github.com/apache/dubbo-go-pixiu/pull/994#discussion_r3610361755


##########
pkg/config/xds/xds.go:
##########
@@ -107,34 +116,51 @@ func (a *Xds) readDubboServiceFromListener() ([]string, 
error) {
        return dubboServices, nil
 }
 
-func (a *Xds) Start() {
+func (a *Xds) Start() error {
        if a.dynamicResourceMg == nil { // if dm is nil, then config not 
initialized.
                logger.Infof("can not get dynamic resource manager. maybe the 
config has not initialized")
-               return
+               return nil
        }
        apiclient.Init(a.clusterMg)
 
+       // lds and cds are independent dynamic resource watches: a failure in 
one must not skip the
+       // other's initialization. Collect each error and fail startup if any 
occurred, so a missing
+       // config or xDS connection failure surfaces to the caller instead of 
leaving the process in a
+       // false-healthy state with parts of the dynamic config unavailable.
+       var errs []error
+
        // lds fetch just run on init phase.
        if a.dynamicResourceMg.GetLds() != nil {
-               a.lds = &LdsManager{
-                       DiscoverApi: 
a.createApiManager(a.dynamicResourceMg.GetLds(), a.dynamicResourceMg.GetNode(), 
constant.ListenerType),
-                       listenerMg:  a.listenerMg,
-               }
-               if err := a.lds.Delta(); err != nil {
-                       logger.Errorf("can not fetch lds err is %+v", err)
+               discoverApi, err := 
a.createApiManager(a.dynamicResourceMg.GetLds(), a.dynamicResourceMg.GetNode(), 
constant.ListenerType)
+               if err != nil {
+                       errs = append(errs, errors.Wrap(err, "create LDS api 
manager"))
+               } else {
+                       a.lds = &LdsManager{
+                               DiscoverApi: discoverApi,
+                               listenerMg:  a.listenerMg,
+                       }
+                       if err := a.lds.Delta(); err != nil {
+                               errs = append(errs, errors.Wrap(err, "fetch 
lds"))
+                       }
                }
        }
        // catch the ongoing cds config change.
        if a.dynamicResourceMg.GetCds() != nil {
-               a.cds = &CdsManager{
-                       DiscoverApi: 
a.createApiManager(a.dynamicResourceMg.GetCds(), a.dynamicResourceMg.GetNode(), 
constant.ClusterType),
-                       clusterMg:   a.clusterMg,
-               }
-               if err := a.cds.Delta(); err != nil {
-                       logger.Errorf("can not fetch lds")
+               discoverApi, err := 
a.createApiManager(a.dynamicResourceMg.GetCds(), a.dynamicResourceMg.GetNode(), 
constant.ClusterType)
+               if err != nil {
+                       errs = append(errs, errors.Wrap(err, "create CDS api 
manager"))

Review Comment:
   当 LDS 和 CDS 像仓库示例一样共用一个 xDS cluster 且首次 gRPC Dial 失败时,LDS 分支会记录错误并继续执行这里的 
CDS 分支。 `GRPCCluster.GetConnection` 的 `sync.Once` 已完成却没有保存首次错误,第二次调用返回 `(nil, 
nil)`,随后 `DeltaExtensionConfigs` 对 nil `ClientConn` 调用 `NewStream` 并再次 
panic,新增的启动错误传播因此失效。 请持久化连接初始化错误或允许安全重试,并增加 LDS/CDS 共用不可达 cluster 时只返回错误、不发生 
panic 的测试。



-- 
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