-
Notifications
You must be signed in to change notification settings - Fork 10.1k
panic: runtime error: comparing uncomparable type map[string]interface {} #19700
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
Comments
Thanks @cruvie for raising the issue. |
@siyuanfoundation Hi, I made a pr which includes two unit tests and |
@cruvie The issue is on the grpc side, they should probably use Meanwhile, we should add @serathius @ahrtr Do you think it is necessary to revert back to google.golang.org/grpc v1.70.0? |
The See also #15145 from 2023. If you are using gRPC APIs that are clearly marked as experimental, you need to vendor gRPC, or you need to consider yourself experimental. If some functionality you need is experimental and there is no way to get it through stable APIs, then I'm always happy to discuss how we can make that happen. gRPC has pending changes we'd like to make to these packages that are mostly just blocked on etcd's lingering usages of these APIs. |
they are working on it grpc/grpc-go#8225 for etcd client next version, I think make a break change to remove
and add Attributes *attributes.Attributes likehttps://github.com/grpc/grpc-go/blob/ce35fd41c56908f4e703e3fd63cf85b2cba9d8f1/resolver/resolver.go#L107 is ok, since Metadata has not been fully tested for a long time?
|
I'm not sure what the right replacement is, until I understand what it is you need to do. It could be that you don't need a custom resolver at all anymore. With the advent of https://pkg.go.dev/google.golang.org/grpc#ClientConnInterface - added in Jan 2020 - I think most of the reasons for having a custom resolver can be replaced by using multiple gRPC channels and wrapping them, similar to how GCP does it: If that wouldn't work: why? |
In my use case, I overlooked the relation between So for my use case add |
etcd itself isn't affected by this problem. But I am not sure whether grpcproxy is affected, because the metadata is set as a struct (which I believe will be a map as well after marshaling & Unmarshaling). Given our grpcproxy related e2e / integration tests all pass, so I assume it isn't affected either. etcd/server/proxy/grpcproxy/register.go Line 75 in 3b66c82
etcd/server/proxy/grpcproxy/register.go Lines 94 to 98 in 3b66c82
So in general, I don't want to patch this local issue. Instead, we should spend more effort on #15145 to resolve such problems once for all. We need to have a summary on existing design/implementation first, and proposals to replace them later, and invite grpc's experts to review. Just updated the #15145 as well. cc. @fuweid @serathius |
For this specific issue, we still expect grpc can fix it, grpc/grpc-go#8227 (comment) For long-term solution, we need experienced contributors can help us to drive/work on #15145
@dfawley Thanks for the comment. As mentioned in #15145 (comment), etcd's usage on grpc-go's resolver package is really very simple and basic, do you think any further change on grpc-go side will break etcd? I may draft a simple google doc to summarize etcd's usage on grpc-go's resolver. |
Generally: anything marked as experimental (e.g. the entire resolver and balancer packages) should not be used by any other library unless that library also declares itself as experimental or vendors grpc-go. We reserve the right to modify or delete any or all of it, though we will try our best to make changes responsibly (provide deprecation notices first, and a migration path to enable a smooth transition). The And as mentioned before, if you believe you need our experimental APIs, I'm happy to discuss other ways you may be able to achieve your goals, or work to find a concrete path toward stabilization. |
Thanks for the feedback.
Theoretically I agree with this. But unfortunately it has been years for etcd to running on grpc-go's experimental features, and maintainers turnover slows down the overall development process. Both etcd and grpc-go are part of the big cloud native ecosystem. We will have to discuss and move forward on this basis.
If you are planning to remove
As we discussed in 15145, i.e. #15145 (comment), completely migrating from the resolver package to other solution (i.e. maintaining & wrapping multiple gRPC channels/connections) is non-trivial effort. But anyway, we can continue the discussion in #15145 |
I don't think we can ever remove the exported resolver package, but it will be undergoing future changes (some of which are explained here), and we should figure out whether there are other options that enable you to move off of it. As referenced above (#19700 (comment)), I wonder if you can use the GCP gRPC connection pool directly even? googleapis/google-api-go-client@bac81c6/transport/grpc/pool.go#L31 |
thx for the feedback. Then we will plan to resolve #19706 (comment). We already evaluated the future changes on grpc-go side about 2 years ago (#15145 (comment)), we don't think it will break etcd. Please correct us if we are wrong. thx
Not only etcd itself uses the resolver package, but also a client utility package (which has already exposed to etcd users for years) use it. refer to https://etcd.io/docs/v3.5/dev-guide/grpc_naming/. Any refactoring might not be a trivial change. Also honestly, we don't have strong motivation to rafactor it as long as the future changes on grpc-go do not break etcd. But we are happy to evaluate any PoC if present. cc @amosehiguese BTW, I just raised a related ticket #19772. |
As covered in the plans, we intend to delete
The reason I'm raising this issue is because I would like to make breaking changes to these experimental APIs. Your usage is the only reason we have not done so yet. By definition, if you are using an experimental API, you become experimental as well, unless you vendor. You cannot be stable if you have unstable dependencies. At some point, we'll have to deal with the pain that these changes will cause. Better to do it ASAP than later. And if possible, it's better if we can find a non-experimental way to move forward, than to change to a new experimental API. |
It's already tracked in #19706. We will fix it.
So we should use/set Endpoint.Addresses?
Yes, I am aware of that and theoretically agreed it. The problem is that there is a user-facing package/utility go.etcd.io/etcd/client/v3/naming/resolver, which has existed for years. It's a breaking change to users.
It's concerning. You mentioned above that the future changes are planned in grpc/grpc-go#6472. My understanding is the direction is to stablize the resolver package. But you also said you might delete at any time. Can you please finalize the grpc-go side change? |
Yes, that is the replacement. An
The good news is that any users doing this also have to use It might be worth taking some time to mark this package as experimental and/or deprecated so that:
The problem only becomes worse over time if you don't make this clear. I think we should also determine if you can provide an similar package that doesn't need experimental APIs to function. Maybe you can provide a Short of any of that, I believe you need to start vendoring gRPC.
This isn't as simple as you make it sound. The API is going to remain experimental until all gRPC library languages (Go, C++, Java, and Node, at least) can agree on the needs and semantics of the name resolver functionality. Since I have no expected end date for that, it would be great if we can pursue any and all alternatives for now instead. |
thx for the confirmation & info. Just raised #19780 to fix it. Currently it assumes each endpoint has only one address (note it keeps the same behaviour as current implementation). If an endpoint has two addresses, then it may be connected by more clients; we will take care of this minor problem separately.
I will bring this to our community meeting. I think we might just want to mark it as experimental (keep consistent with grpc-go), and it may be changed or removed at any time. If the feature gets stable on grpc-go side in future, we may also want to stabilise it by them.
I don't think vendoring is relevant here. Vendoring is for the case of a repo being completely removed. Usually locking on a specific grpc-go version is a workaround for such case.
thx for the feedback. Currently we will mark the user-facing utility package as experimental (to be discussed), and try to resolve the two issues ( In term of other alternative (completely remove resolver), it might not happen any time soon. we will keep discussing it in #15145 |
You’re right, the current use of the resolver.Builder interface in etcd is quite minimal, and from what I’ve seen, it doesn’t seem to use any of the deeper internals of the experimental API beyond UpdateState. If things remain that way, then yeah, breaking changes might not directly affect etcd right now. That said, I think the concern is more future-facing, for example, with gRPC planning to deprecate types like Address in favor of Endpoint, there's potential for the surface area of change to grow. Even if the impact isn’t immediate, it might be worth keeping an eye on how these changes evolve.
The fact that the client utility package also relies on the resolver (and has been exposed to users for a while now) definitely adds more weight to the situation. It’s not just etcd’s internal usage anymore, users have likely built tools and workflows around it, so any refactor here is far from a quick fix.
That’s totally understandable. If things aren’t breaking uncontrollably right now, it makes sense not to rush into a refactor just for the sake of it. However, @dfawley continues to highlight that breaking changes are expected.
Honestly, at this point I’ve kind of run out of PoCs — most of the core ideas and possible directions have already been laid out in this discussion. From adapter patterns (I initially thought of this but requires careful examination still), to vendoring to exploring alternatives like the GCP pool, I think the groundwork is all there now. That said, whatever direction etcd’s team decide to take; whether it's a refactor, a temporary workaround, or just holding off, I’m totally at your disposal. If you want me to expand on any of the ideas, map out trade-offs, or help shape the next steps, just say the word. I'm readily available. cc: @ahrtr |
Bug report criteria
What happened?
use grpc client made by etcd resolver with
google.golang.org/grpc v1.71.0
cause panicWhat did you expect to happen?
call rpc method successfully
How can we reproduce it (as minimally and precisely as possible)?
get a grpc client like this
and use the client call a method
Anything else we need to know?
go 1.24
google.golang.org/grpc v1.70.0 works fine
create a grpc client manually works fine
Etcd version (please run commands below)
deployed by docker
Etcd configuration (command line flags or environment variables)
default
Etcd debug information (please run commands below, feel free to obfuscate the IP address or FQDN in the output)
standalone
Relevant log output
The text was updated successfully, but these errors were encountered: