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]

Reply via email to