Skip to content
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

*: Split etcd into 3 modules: server, client (c), integration #12204

Closed
wants to merge 13 commits into from

Conversation

ptabor
Copy link
Contributor

@ptabor ptabor commented Aug 6, 2020

*: Split etcd into 3 modules:

  • go.etcd.io/etcd/v3 - server
  • go.etcd.io/etcd/c/v3 - client code
  • go.etcd.io/etcd/integration/v3 - integration tests

This was discussed an community meeting on 2020/07/30. The goal is to
minimize number of dependencies that our network customers needs to
carry and clearly define packets that needs to stay backward compatible.

Main files moves into ./c
Clients:
./{client,clientv3}
API protos:
./etcdserver/api/membership/membershippb
./etcdserver/api/v3rpc/rpctypes
./auth/authpb
./mvcc/mvccpb
./etcdserver/etcdserverpb
Integration tests:
./client{v3}/{integration,concurrency} -> ./integration/client{v3}/{integration,concurrency}

Tested using:

  PASSES="unit integration functional e2e" time ./test -v

  ./build

  (go build ./... && go test ./...)
  (cd c; go build ./... && go test ./...)
  (cd integration; go build ./... && go test ./...)

  ./scripts/genproto.sh

  make

  go mod tidy
  go mod vendor

Futher steps to consider:

  • migrate etcdctl into (c) - client code. This requires spliting some admin funtionalities that operate directly on etcd server files.
  • move tests/e2e and functional into integration dir

Please see/comment the attached doc

@ptabor
Copy link
Contributor Author

ptabor commented Aug 6, 2020

\cc @gyuho
\cc @jpbetz

This is the PR that is separating the client code from the server code - discussed on the last community meeting. Please review.

@ptabor ptabor force-pushed the modularization branch 12 times, most recently from afd2e89 to bbcfb34 Compare August 7, 2020 18:53
@ptabor
Copy link
Contributor Author

ptabor commented Aug 7, 2020

Travis is flaky on --- FAIL: TestGetTokenWithoutAuth (39.16s) - that is addressed in #12200

\cc @wojtek-t FYI

@ptabor ptabor force-pushed the modularization branch 3 times, most recently from f30a5f4 to 9e2fcaf Compare August 7, 2020 22:57
@ptabor
Copy link
Contributor Author

ptabor commented Aug 9, 2020

More about motivation and considerations in modularization of etcd doc

@gyuho
Copy link
Contributor

gyuho commented Aug 11, 2020

@ptabor Can we have separate commits? It's hard to review :)

@ptabor
Copy link
Contributor Author

ptabor commented Aug 18, 2020

@gyuho I will split when I'm back from vacations in a week.
Majority of changes here are file moves and import changes.

Interesting changes. go to:

  • go.mod files (./go.mod ./c/go.mod. ./integration/go.mod)
  • ./test file

I would appreciate if could take a look at: ./test file and the overall directory layout structure in the meantime.

/  - will contain server code
/c - will contain client code
/integration - will contain integration tests code
The commit is moving files needed for the client code.
The files are having only imports changed.
The files got moved and the imports got changed.
This logic is solelly used by etcdctl and depends on implementation
details (files layout) of server so connot be kept in the client module.
pkg/logutil is in general dependency of client code,
but zap_raft has dependencies on server code and is used solelly within
the server.
@ptabor
Copy link
Contributor Author

ptabor commented Aug 24, 2020

@gyuho I splitted the change as requested. PTAL

@ptabor
Copy link
Contributor Author

ptabor commented Sep 1, 2020

@gyuho @jpbetz @jingyih @wenjiaswe - please review

Copy link
Contributor

@jpbetz jpbetz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done a first pass review.

Re: Naming the client module c. For the casual observer, or anyone reading go.mod files, it won't be obvious what this is. If there is good rationale on why we can't just call it client? If this was already discussed somewhere can we link to the discussion in description? Else can summarize alternatives and naming decision somewhere for posterity? The community will ask why we chose the name we did since this is a high visibility change that impacts users for the long term.

@@ -0,0 +1,2 @@
# git mod vendor will regenerate the directory
vendor/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be consistent with how we vendor across the etcd project.

Historically we've checked in the /vendor directory so that the project can be built after a git clone without requiring a go mod fetch. Kubernetes does the same thing. My rough understanding is that it offers some advantages in build time (no go mod pulls). If we do decide to change how we vendor, we should probably do it separate from this PR.

Also, If we're going to have multiple vendor directories, this is going to get more complicated. Can we have one vendor directory that all the modules share? Also, we might need tooling like kubernetes has to manage multiple go.mod files sanely (update-vendor.sh, verify-vendor.sh, pin-dependency.sh)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the cleanup of vendor directory to a separate PR: #12279
I performed there multiple tests and:

  • neither "go mod fetch" nor "go mod vendor" is needed. "go build ..." or "./build" works of fresh clients (no $GOPATH)
  • Performance is highly improved. Even if we wipe $GOPATH/pkg, the "./build" takes <10s without vendor and
    ~34s with vendor
    . I think that go mod must download pre-built or pre-analyzed artifacts to have such great improvement.
  • Multiple modules within etcd or in different repositories would share the same pre-loaded modules.

Please let me know in the PR whether I'm missed any benefits / scenarios to keep the ./vendor dir.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very promising. By removing vendor we are adding a build dependency on proxy.golang.org (and requiring a network connection to pull from it). This seems acceptable to me given that the proxy is quite mature at this point. I've added a comment about this on #12279 and nudged a couple maintainers. We can continue the conversation over there.

c/etcdserver/etcdserverpb/raft_internal.pb.go Show resolved Hide resolved
echo "could not find protoc 3.7.1, is it installed + in PATH?"
exit 255
fi
#if [[ $(protoc --version | cut -f2 -d' ') != "3.7.1" ]]; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-enable or add comment explaining why we don't need this any more?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-enabled. Good catch.

Would be happy to add a comment why we need this.
Lookled over changes 3.7..3.12, and there seems nothing go related: https://github.com/protocolbuffers/protobuf/releases?before=v3.7.1.

I assume its to guarantee better repeatability for patch releases.

@@ -50,8 +50,8 @@ USERPKG=${PKG:-}
COVER=${COVER:-"-cover"}

# Hack: gofmt ./ will recursively check the .git directory. So use *.go for gofmt.
IGNORE_PKGS="(vendor/|etcdserverpb|rafttest|gopath.proto|v3lockpb|v3electionpb)"
INTEGRATION_PKGS="(integration|tests/e2e|contrib|functional)"
IGNORE_PKGS="(^|/)(vendor|etcdserverpb|rafttest|gopath.proto|v3lockpb|v3electionpb|c)(/|$)"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think really want to exclude the entire c module from gofmt.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing...

test Show resolved Hide resolved
"${REPO_PATH}/contrib/raftexample")
INTEGTESTPKG=("${REPO_PATH}/contrib/raftexample")
go test -mod=mod -timeout "${USERTIMEOUT}" -v -cpu "${TEST_CPUS}" "${RUN_ARG}" "$@" "${INTEGTESTPKG[@]}"
(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: indentation of this line is odd, doesn't match 195

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing...

etcdserver/api/v3lock/v3lockpb/v3lock.pb.go Show resolved Hide resolved
@@ -27,7 +27,7 @@ github.com/dustin/go-humanize
github.com/etcd-io/gofail/runtime
# github.com/fatih/color v1.7.0
## explicit
# github.com/gogo/protobuf v1.2.1
# github.com/gogo/protobuf v1.2.1 => github.com/gogo/protobuf v1.2.1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems unnecessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing...

@@ -228,3 +256,6 @@ gopkg.in/yaml.v2
# sigs.k8s.io/yaml v1.1.0
## explicit
sigs.k8s.io/yaml
# github.com/gogo/protobuf => github.com/gogo/protobuf v1.2.1
# go.etcd.io/etcd/c/v3 => ./c
# go.etcd.io/etcd/integration/v3 => ./SHOULD_NOT_BE_DEPENDENCY
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. How does this line get added to modules.txt? Is it added manually or do we have some way to make sure it gets added automatically?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a consequence of: 053201d#diff-37aff102a57d3d7b797f152915a6dc16R54 in go.mod

replace (
	go.etcd.io/etcd/integration/v3 => ./SHOULD_NOT_BE_DEPENDENCY
)

A little bit a hack, but very explicit when the error happens.

@ptabor
Copy link
Contributor Author

ptabor commented Sep 10, 2020

Re: Naming the client module "c".

I wrote ideas and motivation for different naming options in this section of the doc:
https://docs.google.com/document/d/19UvKD7by_fEkzLMRi-QNSKEed4kYAW286S3DsNRPDOM/edit#heading=h.rj04ue628kji

Happy to change them - agree that current choice might be sub-optimal.
My intuitions goes toward: go.etcd.io/etcd/client/v3, go.etcd.io/etcd/server/v3, go.etcd.io/etcd/tests/v3

@gyuho @jpbetz @jingyih @cfc4n et al. - please comment (here or in the doc)

@jpbetz
Copy link
Contributor

jpbetz commented Sep 10, 2020

go.etcd.io/etcd/client/v3, go.etcd.io/etcd/server/v3 and go.etcd.io/etcd/tests/v3 look great to me

@gyuho
Copy link
Contributor

gyuho commented Sep 10, 2020

go.etcd.io/etcd/client/v3, go.etcd.io/etcd/server/v3 and go.etcd.io/etcd/tests/v3 look great to me

+1

Thanks for cleaning this up @ptabor

@gyuho
Copy link
Contributor

gyuho commented Sep 10, 2020

/cc @philips

@philips
Copy link
Contributor

philips commented Sep 12, 2020

The motivation doc from @ptabor looks great. The overall outcome seems good.

However, I don’t have time to review. But, it looks like @jpbetz is on the case.

Thanks for working on this!

@ptabor
Copy link
Contributor Author

ptabor commented Sep 12, 2020

Thank you. I will let you know when its ready for another pass.

I'm creating smaller PRs like:

That are preparing this refactoring, so having them merged is a dependency.

@sagikazarmark
Copy link

@ptabor what's the status of this PR? Can I help?

@ptabor
Copy link
Contributor Author

ptabor commented Sep 22, 2020

@ptabor sagikazarmark

#12322 (so also
#12319) are the last 2 PRs, I want to get in before rebaseing this PR,
as they will:

  • make the changes to ./test smaller
  • give me confidence I'm not breaking anything as part of this process.

@sagikazarmark
Copy link

Cool, thanks for the update!

@stale
Copy link

stale bot commented Dec 27, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 21 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Dec 27, 2020
@ptabor
Copy link
Contributor Author

ptabor commented Jan 7, 2021

I'm considering this effort done.
Getting the release of 3.5.0-alpha.0 (#12498) would be a cherry on top of this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

5 participants