dlmarion commented on code in PR #4439:
URL: https://github.com/apache/accumulo/pull/4439#discussion_r1561527673
##########
server/tserver/src/main/java/org/apache/accumulo/tserver/TabletClientHandler.java:
##########
@@ -1096,80 +1097,47 @@ public List<TKeyExtent> refreshTablets(TInfo tinfo,
TCredentials credentials,
// handle that more expensive case if needed.
var tabletsSnapshot = server.getOnlineTablets();
- Set<KeyExtent> notFound = new HashSet<>();
+ Map<KeyExtent,Tablet.RefreshSession> refreshSessions = new HashMap<>();
+
+ // Created this as synchronized list because it passed to a lambda that
could possibly run in
Review Comment:
```suggestion
// Created this as synchronized list because it's passed to a lambda
that could possibly run in
```
##########
server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/Tablet.java:
##########
@@ -1551,40 +1569,88 @@ public enum RefreshPurpose {
MINC_COMPLETION, REFRESH_RPC, FLUSH_ID_UPDATE, LOAD
}
- public void refreshMetadata(RefreshPurpose refreshPurpose) {
+ public class RefreshSession {
+
+ private final long observedRefreshCount;
+
+ private RefreshSession(long observedRefreshCount) {
+ this.observedRefreshCount = observedRefreshCount;
+ }
+
+ /**
+ * Refresh tablet metadata using metadata that was read separately.
+ *
+ * @param tabletMetadata this tablet metadata must have been read after
calling
+ * {@link Tablet#startRefresh()}
+ */
+ public boolean refreshMetadata(RefreshPurpose refreshPurpose,
TabletMetadata tabletMetadata) {
+ return Tablet.this.refreshMetadata(refreshPurpose, observedRefreshCount,
tabletMetadata);
+ }
+ }
+
+ /**
+ * A refresh session allows code outside of this class to safely read tablet
metadata and pass it
+ * back. This is useful for the case where many tablets need to be refreshed
and we want to batch
+ * reading their metadata. Creating a refresh session will not block. A
refresh session is able to
+ * detect changes in tablet metadata that happen during its existence and
reread tablet metadata
+ * if necessary.
+ */
+ public RefreshSession startRefresh() {
+ return new RefreshSession(latestMetadata.get().refreshCount);
+ }
+
+ private boolean refreshMetadata(RefreshPurpose refreshPurpose, Long
observedRefreshCount,
+ TabletMetadata tabletMetadata) {
+
refreshLock.lock();
try {
+ var prevMetadata = latestMetadata.get();
+ // if the tablet metadata passed in is stale, then reread it
+ if (observedRefreshCount == null ||
!observedRefreshCount.equals(prevMetadata.refreshCount)) {
+ if (observedRefreshCount != null) {
+ log.debug(
+ "Metadata read outside of refresh lock is no longer valid,
rereading metadata. {} {} {}",
+ extent, observedRefreshCount, prevMetadata.refreshCount);
+ }
Review Comment:
Seems like this will always be printed to the log when
`!observedRefreshCount.equals(prevMetadata.refreshCount)`. Is that the
intention?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]