AlexStocks commented on code in PR #3488:
URL: https://github.com/apache/dubbo-go/pull/3488#discussion_r3578175764
##########
common/url.go:
##########
@@ -1163,26 +1195,91 @@ func IsEquals(left *URL, right *URL, excludes
...string) bool {
return false
}
- leftMap := left.ToMap()
- rightMap := right.ToMap()
- for _, exclude := range excludes {
- delete(leftMap, exclude)
- delete(rightMap, exclude)
+ excluded := newKeySet(excludes)
+ return equalScalars(left, right, excluded) &&
+ equalLocation(left.Location, right.Location, excluded) &&
+ equalParams(left, right, excluded)
+}
+
+// equalScalars compares the non-param scalar fields of two URLs, skipping any
excluded key.
+func equalScalars(left, right *URL, excluded keySet) bool {
+ scalars := []struct {
+ key string
+ left, right string
+ }{
+ {constant.ProtocolKey, left.Protocol, right.Protocol},
+ {constant.UsernameKey, left.Username, right.Username},
+ {constant.PasswordKey, left.Password, right.Password},
+ {constant.PathKey, left.Path, right.Path},
}
+ for _, s := range scalars {
+ if s.left != s.right && !excluded.contains(s.key) {
+ return false
+ }
+ }
+ return true
+}
- if len(leftMap) != len(rightMap) {
+// equalLocation compares two "host:port" locations, skipping host and/or port
when excluded.
+func equalLocation(left, right string, excluded keySet) bool {
+ if left == right {
+ return true
+ }
+
+ hostExcluded := excluded.contains(constant.HostKey)
+ portExcluded := excluded.contains(constant.PortKey)
+ if hostExcluded && portExcluded {
+ return true
+ }
+
+ leftHost, leftPort := parseLocation(left)
+ rightHost, rightPort := parseLocation(right)
+ if !hostExcluded && leftHost != rightHost {
+ return false
+ }
+ if !portExcluded && leftPort != rightPort {
return false
}
+ return true
+}
- for lk, lv := range leftMap {
- if rv, ok := rightMap[lk]; !ok {
- return false
- } else if lv != rv {
+// equalParams compares the params of two URLs, skipping excluded keys. It
avoids
+// materializing both maps by snapshotting only the left side and streaming
the right.
+func equalParams(left, right *URL, excluded keySet) bool {
+ leftParams := make(map[string]string)
+ left.RangeParams(func(key, value string) bool {
Review Comment:
[P1] 这里改变了保留键的覆盖语义
旧实现先调用 `ToMap()`,因此 `Protocol/Username/Password/Location/Path` 会覆盖 params
中同名的 `protocol/username/password/host/port/path`;这里又无差别比较原始 params,导致最终扁平 URL
完全相同的对象被判为不相等。WSL 差分探针中,两侧字段 `Protocol` 都是 `consumer`,但 `params["protocol"]`
分别为 `tri`/`dubbo`:两侧 `ToMap()` 都得到 `protocol:consumer`,旧 `IsEquals` 返回
`true`,新实现返回 `false`。仓库的 consumer URL 构造路径确实会同时设置字段协议和 query 参数协议,这会触发不必要的
Invoker 重建/销毁。建议保持旧 `ToMap` 的覆盖优先级,并为六个保留键补冲突、exclude 和左右对称用例。
--
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]