-
Notifications
You must be signed in to change notification settings - Fork 726
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
client: Introduce ServiceClient
#7489
Conversation
Signed-off-by: Cabinfever_B <[email protected]>
[REVIEW NOTIFICATION] This pull request has been approved by:
To complete the pull request process, please ask the reviewers in the list to review by filling The full list of commands accepted by this bot can be found here. Reviewer can indicate their review by submitting an approval review. |
/cc @niubell |
@CabinfeverB: GitHub didn't allow me to request PR reviews from the following users: niubell. Note that only tikv members and repo collaborators can review this PR, and authors cannot review their own PRs. In response to this:
Instructions 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. |
Signed-off-by: Cabinfever_B <[email protected]>
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## master #7489 +/- ##
==========================================
- Coverage 74.75% 74.75% -0.01%
==========================================
Files 457 459 +2
Lines 50415 50541 +126
==========================================
+ Hits 37686 37780 +94
- Misses 9394 9412 +18
- Partials 3335 3349 +14
Flags with carried forward coverage won't be shown. Click here to find out more. |
client/pd_service_discovery.go
Outdated
Available() bool | ||
// CheckAvailable checks the status about network connection or other availability of the current service client | ||
CheckAvailable() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the difference?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CheckAvailable
is used to try to mark the client as available if it is in unavailable state. It's not quite the right name. Any suggestion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then, why not merge these two?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let me have a try
client/pd_service_discovery.go
Outdated
// CheckNetworkAvailable checks if the network connection for the current service client is available | ||
CheckNetworkAvailable(context.Context) | ||
// RespToErr checks if client need to retry based on the PD server error response. | ||
RespToErr(*pdpb.Error, error) bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need a method to mark the follower client as unavailable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about just NeedRetry/IsRetryable or something similar?
Signed-off-by: Cabinfever_B <[email protected]>
Signed-off-by: Cabinfever_B <[email protected]>
Signed-off-by: Cabinfever_B <[email protected]>
Signed-off-by: Cabinfever_B <[email protected]>
client/pd_service_discovery.go
Outdated
i := 0 | ||
defer c.mu.Unlock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exchange these two?
return nil | ||
} | ||
for ; i < c.totalNode; i++ { | ||
if c.now.Available() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's not available, will it be excluded in the next round?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. I don't remove unavailable nodes from the queue. The simple approach is taken now and can be optimized in the future if needed
client/pd_service_discovery.go
Outdated
// mustLeader: whether must send to leader. | ||
BuildGRPCContext(ctx context.Context, mustLeader bool) context.Context | ||
// IsLeader returns whether the target PD server is leader. | ||
IsLeader() bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the leader changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If leader changes, it will create new ServiceClient and store it in leader
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about targetIsLeader or something else?
Signed-off-by: Cabinfever_B <[email protected]>
client/pd_service_discovery.go
Outdated
} | ||
|
||
// BuildGRPCContext implements ServiceClient. | ||
func (c *pdServiceClient) BuildGRPCContext(ctx context.Context, toLeader bool) context.Context { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the difference between toLeader and isLeader?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function of the ServiceClient
is to interact with a PD server, which may be a follower or leader. When a client sends a request to a server, mutLeader
is true if the request is forwarded to the leader. Otherwise, it is sent to the server to process the request, and mutLeader
is false.
|
||
// pdServiceBalancer is a load balancer for PD service clients. | ||
// It is used to balance the request to all servers and manage the connections to multiple PD service nodes. | ||
type pdServiceBalancer struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about supporting multiple policies? And make the round-robin a common library?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a bit confused here because it seems that there is forwarding logic in the internal ServiceClient
, and now we have introduced an additional layer of the load balancer. Will these two things conflict with each other?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a bit confused here because it seems that there is forwarding logic in the internal
ServiceClient
, and now we have introduced an additional layer of the load balancer. Will these two things conflict with each other?
There will be no conflict. In the past, followers were randomly selected for forwarding, but now it is in turn
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about supporting multiple policies? And make the round-robin a common library?
I've thought about it. Since it is observed that there is now only one Round-Robin balancer in /pkg/balancer
, I haven't implemented multiple policies yet
@JmPotato PTAL~ |
client/pd_service_discovery.go
Outdated
// BuildGRPCContext builds a context object with a gRPC context. | ||
// ctx: the original context object. | ||
// mustLeader: whether must send to leader. | ||
BuildGRPCContext(ctx context.Context, mustLeader bool) context.Context |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the name, it's hard to tell what this build is for. Suggest using a more specified name like BuildGRPCTargetContext
.
client/pd_service_discovery.go
Outdated
var _ ServiceClient = (*pdServiceClient)(nil) | ||
var _ ServiceClient = (*pdServiceAPIClient)(nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var _ ServiceClient = (*pdServiceClient)(nil) | |
var _ ServiceClient = (*pdServiceAPIClient)(nil) | |
var ( | |
_ ServiceClient = (*pdServiceClient)(nil) | |
_ ServiceClient = (*pdServiceAPIClient)(nil) | |
) |
client/pd_service_discovery.go
Outdated
networkFailure atomic.Bool | ||
} | ||
|
||
func newPDServiceClient(addr, leaderAddr string, conn *grpc.ClientConn, isLeader bool) *pdServiceClient { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe using the interface as the returned value is better.
func newPDServiceClient(addr, leaderAddr string, conn *grpc.ClientConn, isLeader bool) *pdServiceClient { | |
func newPDServiceClient(addr, leaderAddr string, conn *grpc.ClientConn, isLeader bool) ServiceClient { |
} | ||
|
||
// NetworkAvailable implements ServiceClient. | ||
func (c *pdServiceClient) Available() bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the judgment condition is whether there is a network error, would Reachable
be a better name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pdServiceAPIClient
checks the network and availability
|
||
// pdServiceBalancer is a load balancer for PD service clients. | ||
// It is used to balance the request to all servers and manage the connections to multiple PD service nodes. | ||
type pdServiceBalancer struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a bit confused here because it seems that there is forwarding logic in the internal ServiceClient
, and now we have introduced an additional layer of the load balancer. Will these two things conflict with each other?
Signed-off-by: Cabinfever_B <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rest LGTM.
client/go.mod
Outdated
@@ -19,6 +20,8 @@ require ( | |||
google.golang.org/grpc v1.54.0 | |||
) | |||
|
|||
require google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need format
client/pd_service_discovery.go
Outdated
// mustLeader: whether must send to leader. | ||
BuildGRPCContext(ctx context.Context, mustLeader bool) context.Context | ||
// IsLeader returns whether the target PD server is leader. | ||
IsLeader() bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about targetIsLeader or something else?
Signed-off-by: Cabinfever_B <[email protected]>
Signed-off-by: Cabinfever_B <[email protected]>
client/testutil/check_env.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the name check_env_dummy.go
is better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also renamed the file in /pkg/utils/tempurl. PTAL
Signed-off-by: Cabinfever_B <[email protected]>
Signed-off-by: Cabinfever_B <[email protected]>
Signed-off-by: Cabinfever_B <[email protected]>
/merge |
@CabinfeverB: It seems you want to merge this PR, I will help you trigger all the tests: /run-all-tests You only need to trigger
Instructions 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 ti-community-infra/tichi repository. |
This pull request has been accepted and is ready to merge. Commit hash: 970cc22
|
@CabinfeverB: Your PR was out of date, I have automatically updated it for you. If the CI test fails, you just re-trigger the test that failed and the bot will merge the PR for you after the CI passes. Instructions 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 ti-community-infra/tichi repository. |
What problem does this PR solve?
Issue Number: ref #7431 ref #7576
What is changed and how does it work?
This PR introduce the interface
ServiceClient
which can get the gRPC client of a specific gRPC server in a PD cluster. It can send request to the follower including follower-handle or forward.And also a balancer is introduced.
Some tools have been added to client to make it possible to run integration tests in the client package. The reason for adding it to the client package is that ServiceClient should be invisible to the caller, so it cannot be tested well in
tests/integrations
.Check List
Tests
Code changes
Side effects
Related changes
pingcap/docs
/pingcap/docs-cn
:pingcap/tiup
:Release note