This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Give the server information about client's remote index protocol version
ClosedPublic

Authored by kbobyrev on Oct 21 2020, 2:55 AM.

Details

Summary

And also introduce package versioning. This is a breaking change, so both clients and servers have to be updated to the new version.

Diff Detail

Event Timeline

kbobyrev created this revision.Oct 21 2020, 2:55 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 21 2020, 2:55 AM
kbobyrev requested review of this revision.Oct 21 2020, 2:55 AM
kbobyrev added inline comments.Oct 21 2020, 3:27 AM
clang-tools-extra/clangd/index/remote/ProtocolVersion.h
4 ↗(On Diff #299617)

Not sure if having a separate file with a hard-coded string is a good idea, should I use something like ProtocolVersion.inc and have a macro definition there?

Regarding versioning of grpc layer. In addition to including a version number in every request, looks like there's the concept of "versioned-services".

So we basically change the package name to be versioned, i.e. package clang.clangd.remote.v1 and every time we make a breaking change, we increment the version number and start a new service (while keeping the old one).
Hopefully most of the core pieces will be re-usable, hence this will likely only end up adding a new service definition with possibly new reply/request types.

That might be more manageable than having a version in every request. It will also make handling a little bit easier, as dispatch will happen in grpc layer and server wouldn't have to perform conditional checks.

What's the goal here?

There are at least 3 mechanisms we can use to mitigate client/server skew:

  1. extending payloads in compatible way, so mismatched versions result in correct behavior (switching from proto3 to proto2 gives us more options here if it's possible)
  2. signalling the version in-band as in this patch
  3. defining a new incompatible protocol with a new name, as in versioned services

IME 1 is the most maintainable way to handle minor changes, while 3 is the most maintainable way to handle dramatic changes. Maybe there's an intermediate spot where 2 is the best option, but I'd like to understand concretely what scenario we might be solving.

OTOH, including/logging client version to make it easier to *debug* errors, without changing server logic, makes a lot of sense.
In that case we should use the VCS version (the version included in clangd --version) so we don't have another string we need to bump.

clang-tools-extra/clangd/index/remote/Index.proto
59

rather than add this to every message, can we use ClientContext::AddMetadata to do this in a cross-cutting way?

IME 1 is the most maintainable way to handle minor changes, while 3 is the most maintainable way to handle dramatic changes.

(I realize I haven't backed this up - it's basically about how many codepaths you have to maintain for how long, and how complex they are. Happy to get into details if it's useful, but didn't want to derail too much)

kbobyrev updated this revision to Diff 299932.Oct 22 2020, 5:21 AM
kbobyrev marked an inline comment as done.

Use ClientContext::AddMetadata to propagate VCS version info.

kbobyrev updated this revision to Diff 299933.Oct 22 2020, 5:22 AM

Remove formatting change.

Regarding versioning of grpc layer. In addition to including a version number in every request, looks like there's the concept of "versioned-services".

So we basically change the package name to be versioned, i.e. package clang.clangd.remote.v1 and every time we make a breaking change, we increment the version number and start a new service (while keeping the old one).
Hopefully most of the core pieces will be re-usable, hence this will likely only end up adding a new service definition with possibly new reply/request types.

That might be more manageable than having a version in every request. It will also make handling a little bit easier, as dispatch will happen in grpc layer and server wouldn't have to perform conditional checks.

Good point! @sammccall should we do the package versioning and update to mitigate potential breaking changes?

Harbormaster completed remote builds in B76018: Diff 299932.
sammccall accepted this revision.Oct 22 2020, 6:31 AM

Regarding versioning of grpc layer. In addition to including a version number in every request, looks like there's the concept of "versioned-services".

So we basically change the package name to be versioned, i.e. package clang.clangd.remote.v1 and every time we make a breaking change, we increment the version number and start a new service (while keeping the old one).
Hopefully most of the core pieces will be re-usable, hence this will likely only end up adding a new service definition with possibly new reply/request types.

That might be more manageable than having a version in every request. It will also make handling a little bit easier, as dispatch will happen in grpc layer and server wouldn't have to perform conditional checks.

Good point! @sammccall should we do the package versioning and update to mitigate potential breaking changes?

Yep, tacking "v1" on this preemptively SGTM.

Note this itself is a breaking change :-)

This revision is now accepted and ready to land.Oct 22 2020, 6:31 AM
kbobyrev updated this revision to Diff 300066.Oct 22 2020, 12:14 PM

Add package versioning and make current version v1.

kbobyrev edited the summary of this revision. (Show Details)Oct 22 2020, 12:19 PM
sammccall requested changes to this revision.Oct 22 2020, 12:33 PM

Add package versioning and make current version v1.

Sorry, I didn't mean in this patch - seems not that related.... up to you whether to tie them together.

I don't think we need to put the actual messages into versioned namespaces, it makes a mess of the code. (We may need to do this later for some messages if we actually make use of this versioning, but we should pay for it if we use it - moving messages between namespaces is a backwards-compatible change)

This revision now requires changes to proceed.Oct 22 2020, 12:33 PM
This revision was not accepted when it landed; it landed in state Needs Revision.Oct 22 2020, 12:35 PM
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.