WIP: implement initial set of MCP enhancements #10635
WIP: implement initial set of MCP enhancements #10635ayj wants to merge 16 commits intoistio:release-1.1from
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: ayj If they are not already assigned, you can assign the PR to them by writing The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
cc @Nino-K @jeffmendoza @ozevren This PR includes istio/api#741 and #10628. The relevant commit to this PR is ae865f3 |
pkg/mcp/source/source.go
Outdated
There was a problem hiding this comment.
nackLimitFreq is unused (from deadcode)
pkg/mcp/sink/sink_test.go
Outdated
There was a problem hiding this comment.
recvError is unused (from deadcode)
pkg/mcp/sink/server.go
Outdated
There was a problem hiding this comment.
connections is unused (from structcheck)
pkg/mcp/snapshot/snapshot.go
Outdated
There was a problem hiding this comment.
typeURL is unused (from structcheck)
pkg/mcp/source/server.go
Outdated
There was a problem hiding this comment.
connections is unused (from structcheck)
pkg/mcp/sink/sink_test.go
Outdated
There was a problem hiding this comment.
error var updateError should have name of the form errFoo (from golint)
pkg/mcp/source/source.go
Outdated
There was a problem hiding this comment.
type name will be used as source.SourceStream by other packages, and that stutters; consider calling this Stream (from golint)
pkg/mcp/source/source_test.go
Outdated
There was a problem hiding this comment.
error var sendError should have name of the form errFoo (from golint)
pkg/mcp/sink/journal_test.go
Outdated
There was a problem hiding this comment.
File is not goimports-ed (from goimports)
pkg/mcp/source/source_test.go
Outdated
There was a problem hiding this comment.
makeWatchResponse - typeURL always receives test.FakeType0TypeURL ("type.googleapis.com/istio.io.galley.pkg.mcp.server.FakeType0") (from unparam)
ae865f3 to
6e619bf
Compare
pkg/mcp/sink/sink_test.go
Outdated
There was a problem hiding this comment.
errRecv is unused (from varcheck)
pkg/mcp/source/server_source.go
Outdated
There was a problem hiding this comment.
connections is unused (from structcheck)
pkg/mcp/source/client_source.go
Outdated
There was a problem hiding this comment.
File is not goimports-ed (from goimports)
geeknoid
left a comment
There was a problem hiding this comment.
I'm surprised to see these abstractions with mutual exclusion logic. Are these really going to be used by multiple concurrent callers? When?
pkg/mcp/sink/journal.go
Outdated
There was a problem hiding this comment.
Does this object init need to happen under lock or could it be moved out? Putting it under lock ensures that all the RecentRequestInfo instance are inserted in time order, but is that needed? At least, the call to proto.Clone could be done outside the lock.
There was a problem hiding this comment.
Good catch. I moved it outside the lock. We can optimize this further and remove the proto clone if we treat the request proto as immutable. One less memory allocation in the client/sink path.
pkg/mcp/sink/journal.go
Outdated
There was a problem hiding this comment.
Is this really what you want here? I think this will end up allocating an ever-increasing array under the covers.
There was a problem hiding this comment.
This was copy/pasted from the original MCP journal code. I think the same concern was raised during the review of that code, but @ozevren said the golang runtime would reclaim the memory. In any case, I rewrote to use a fixed slice without additional memory allocations.
pkg/mcp/sink/server_sink.go
Outdated
There was a problem hiding this comment.
failus -> failures
logs as a -> logged in a
pkg/mcp/sink/server_sink.go
Outdated
There was a problem hiding this comment.
I think it's bad form to have an otherwise reentrant library pull in state from the ambient environment. I would prefer if these values came in as arguments when initializing this package, and let the wrapping command read the environment and supply the values.
That is, environment variables should handled like command-line arguments and read by the top-level command code.
There was a problem hiding this comment.
Fair enough. I've moved the envvar handling out of the common mcp packages and into the galley/configmap loading code. I've also added Option structs to the source/sink packages where callers can optionally set these sorts of overrides in addition to the other required parameters.
pkg/mcp/sink/server_sink.go
Outdated
There was a problem hiding this comment.
If ServerSink a thread-safe abstraction? I wasn't expecting it to be...
There was a problem hiding this comment.
It's minimally thread-safe. The majority of state is per-connection/stream. The extra atomic check here prevents the case of multiple sources connecting, which isn't supported (yet). Eventually, Galley may status from multiple Pilot instances, in which case a single sink server may have multiple source connections.
pkg/mcp/sink/sink.go
Outdated
pkg/mcp/sink/sink.go
Outdated
There was a problem hiding this comment.
When is a sink used in a multithread environment?
There was a problem hiding this comment.
The lock here protects the per-type resource version state. This state is used in the request path for fast-resume on re-connection. The caller can invoke ResetResourceVersions() to reset this version information and force a full state delivery. This function is invoked outside of the normal request path and must therefore protect access to the state with a lock.
There was a problem hiding this comment.
Given this is a utility package that several components will use, it'd worth stating the multithreading expectations/support explicitly in a comment.
pkg/mcp/source/source_test.go
Outdated
There was a problem hiding this comment.
h can be Watcher (from interfacer)
galley/tools/gen-meta/main.go
Outdated
There was a problem hiding this comment.
struct field tag json:- not compatible with reflect.StructTag.Get: bad syntax for struct tag value (from govet)
galley/tools/gen-meta/main.go
Outdated
There was a problem hiding this comment.
struct field tag json:- not compatible with reflect.StructTag.Get: bad syntax for struct tag value (from govet)
There was a problem hiding this comment.
ineffectual assignment to byNamespace (from ineffassign)
pkg/mcp/snapshot/snapshot_test.go
Outdated
There was a problem hiding this comment.
fakeResource2 is unused (from varcheck)
pkg/mcp/snapshot/snapshot_test.go
Outdated
There was a problem hiding this comment.
fakeResource1 is unused (from varcheck)
pkg/mcp/snapshot/snapshot_test.go
Outdated
There was a problem hiding this comment.
fakeResource0 is unused (from varcheck)
pkg/mcp/snapshot/inmemory_test.go
Outdated
There was a problem hiding this comment.
mustMarshalAny is unused (from deadcode)
There was a problem hiding this comment.
addedTracking is unused (from deadcode)
There was a problem hiding this comment.
obj is unused (from structcheck)
There was a problem hiding this comment.
updated is unused (from structcheck)
There was a problem hiding this comment.
I think so. This PR still has some TODO's around optimizing ServiceEntry updates and invoking ConfigUpdate() directly that we'll still need to address in a follow-up PR
pkg/mcp/configz/configz_test.go
Outdated
pkg/mcp/sink/sink.go
Outdated
There was a problem hiding this comment.
It would be nice to call this New so the caller can do sink.New as oppose to sink.NewSink, but very minor.
pkg/mcp/sink/client_sink.go
Outdated
pkg/mcp/sink/sink.go
Outdated
There was a problem hiding this comment.
Just curious why is this needed? if no update received for a resource within a time frame it is destined to be removed.
048179d to
19063a5
Compare
19063a5 to
81497ac
Compare
81497ac to
c43172b
Compare
There was a problem hiding this comment.
ineffectual assignment to err (from ineffassign)
4b99dbb to
b54ae47
Compare
3933efa to
c40901c
Compare
| // We can do this, because there is no error that can be raised from now on. | ||
| b.state.items[kind] = newTypeState | ||
| for key, val := range added { | ||
| collection, found := b.state.items[key.Kind] |
There was a problem hiding this comment.
ineffectual assignment to collection (from ineffassign)
|
@ayj: The following tests failed, say
DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
|
@ayj: PR needs rebase. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
| func (b *SchemaBuilder) Register(typeURL string) Info { | ||
| if _, found := b.schema.byURL[typeURL]; found { | ||
| panic(fmt.Sprintf("schema.Register: Proto type is registered multiple times: %q", typeURL)) | ||
| func (b *SchemaBuilder) Register(rawCollection, typeURL string) Info { |
There was a problem hiding this comment.
I thought we replace typeURL with collection, why do we keep them both?
There was a problem hiding this comment.
A collection has a corresponding schema (e.g. typeURL) defined by the proto. This mapping is defined in galley/tools/gen-meta/metadata.yaml and is registered at runtime here. The typeURL is used elsewhere to allocate new protobuf instances of the correct type.
This introduces the initial set of MCP enhancements as described by the MCP enhancements design proposal. The existing client/server implementation is retained, though several internal interfaces have been refactored so both implementations can coexist during migration.