@@ -41,27 +41,48 @@ public class TiRegion implements Serializable {
4141 private final Region meta ;
4242 private final IsolationLevel isolationLevel ;
4343 private final Kvrpcpb .CommandPri commandPri ;
44- private Peer peer ;
44+ private Peer leader ;
45+ private int followerIdx = 0 ;
46+ private final boolean isReplicaRead ;
4547
4648 public TiRegion (
4749 Region meta ,
48- Peer peer ,
50+ Peer leader ,
4951 IsolationLevel isolationLevel ,
5052 Kvrpcpb .CommandPri commandPri ,
5153 KVMode kvMode ) {
54+ this (meta , leader , isolationLevel , commandPri , kvMode , false );
55+ }
56+
57+ public TiRegion (
58+ Region meta ,
59+ Peer leader ,
60+ IsolationLevel isolationLevel ,
61+ Kvrpcpb .CommandPri commandPri ,
62+ KVMode kvMode ,
63+ boolean isReplicaRead ) {
5264 Objects .requireNonNull (meta , "meta is null" );
5365 this .meta = decodeRegion (meta , kvMode == KVMode .RAW );
54- if (peer == null || peer .getId () == 0 ) {
66+ if (leader == null || leader .getId () == 0 ) {
5567 if (meta .getPeersCount () == 0 ) {
5668 throw new TiClientInternalException ("Empty peer list for region " + meta .getId ());
5769 }
5870 // region's first peer is leader.
59- this .peer = meta .getPeers (0 );
71+ this .leader = meta .getPeers (0 );
6072 } else {
61- this .peer = peer ;
73+ this .leader = leader ;
74+ }
75+ if (isReplicaRead && meta .getPeersCount () > 0 ) {
76+ // try to get first follower
77+ try {
78+ getNextFollower ();
79+ } catch (Exception ignore ) {
80+ // ignore
81+ }
6282 }
6383 this .isolationLevel = isolationLevel ;
6484 this .commandPri = commandPri ;
85+ this .isReplicaRead = isReplicaRead ;
6586 }
6687
6788 private Region decodeRegion (Region region , boolean isRawRegion ) {
@@ -89,7 +110,24 @@ private Region decodeRegion(Region region, boolean isRawRegion) {
89110 }
90111
91112 public Peer getLeader () {
92- return peer ;
113+ return leader ;
114+ }
115+
116+ public Peer getCurrentFollower () {
117+ return meta .getPeers (followerIdx );
118+ }
119+
120+ public Peer getNextFollower () {
121+ int cnt = meta .getPeersCount ();
122+ for (int retry = cnt - 1 ; retry > 0 ; retry --) {
123+ followerIdx = (followerIdx + 1 ) % cnt ;
124+ Peer cur = meta .getPeers (followerIdx );
125+ if (cur .getIsLearner ()) {
126+ continue ;
127+ }
128+ return cur ;
129+ }
130+ return leader ;
93131 }
94132
95133 public List <Peer > getLearnerList () {
@@ -130,7 +168,18 @@ public Kvrpcpb.Context getContext(Set<Long> resolvedLocks) {
130168 Kvrpcpb .Context .Builder builder = Kvrpcpb .Context .newBuilder ();
131169 builder .setIsolationLevel (this .isolationLevel );
132170 builder .setPriority (this .commandPri );
133- builder .setRegionId (meta .getId ()).setPeer (this .peer ).setRegionEpoch (this .meta .getRegionEpoch ());
171+ if (isReplicaRead ) {
172+ builder
173+ .setRegionId (meta .getId ())
174+ .setPeer (getCurrentFollower ())
175+ .setReplicaRead (true )
176+ .setRegionEpoch (this .meta .getRegionEpoch ());
177+ } else {
178+ builder
179+ .setRegionId (meta .getId ())
180+ .setPeer (this .leader )
181+ .setRegionEpoch (this .meta .getRegionEpoch ());
182+ }
134183 builder .addAllResolvedLocks (resolvedLocks );
135184 return builder .build ();
136185 }
@@ -152,7 +201,7 @@ boolean switchPeer(long leaderStoreID) {
152201 List <Peer > peers = meta .getPeersList ();
153202 for (Peer p : peers ) {
154203 if (p .getStoreId () == leaderStoreID ) {
155- this .peer = p ;
204+ this .leader = p ;
156205 return true ;
157206 }
158207 }
@@ -186,7 +235,7 @@ public boolean contains(ByteString key) {
186235 }
187236
188237 public boolean isValid () {
189- return peer != null && meta != null ;
238+ return leader != null && meta != null ;
190239 }
191240
192241 public Metapb .RegionEpoch getRegionEpoch () {
@@ -204,14 +253,14 @@ public boolean equals(final Object another) {
204253 }
205254 TiRegion anotherRegion = ((TiRegion ) another );
206255 return anotherRegion .meta .equals (this .meta )
207- && anotherRegion .peer .equals (this .peer )
256+ && anotherRegion .leader .equals (this .leader )
208257 && anotherRegion .commandPri .equals (this .commandPri )
209258 && anotherRegion .isolationLevel .equals (this .isolationLevel );
210259 }
211260
212261 @ Override
213262 public int hashCode () {
214- return Objects .hash (meta , peer , isolationLevel , commandPri );
263+ return Objects .hash (meta , leader , isolationLevel , commandPri );
215264 }
216265
217266 @ Override
0 commit comments