This is an automated email from the ASF dual-hosted git repository.

ctubbsii pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo-classloaders.git


The following commit(s) were added to refs/heads/main by this push:
     new a135d9c  Verify hard links before use (#61)
a135d9c is described below

commit a135d9c9bb07d41622e3d2ae15a89cc3cdfb815e
Author: Christopher Tubbs <[email protected]>
AuthorDate: Wed Feb 4 15:18:47 2026 -0500

    Verify hard links before use (#61)
    
    Move existing file verification to after the hard links are created to
    avoid redundant verification of local files while other processes are
    downloading other files, and to ensure the file actually being used by
    the classloader has been verified.
    
    This also moves the staging of the resources from the loader function's
    parameter Supplier to the loader function (LccUtils.createClassLoader),
    which simplifies the code slightly.
    
    This fixes #59
---
 .../lcc/LocalCachingContextClassLoaderFactory.java         |  9 ++-------
 .../org/apache/accumulo/classloader/lcc/util/LccUtils.java | 10 +++++++---
 .../apache/accumulo/classloader/lcc/util/LocalStore.java   | 14 +++++++++++---
 3 files changed, 20 insertions(+), 13 deletions(-)

diff --git 
a/modules/local-caching-classloader/src/main/java/org/apache/accumulo/classloader/lcc/LocalCachingContextClassLoaderFactory.java
 
b/modules/local-caching-classloader/src/main/java/org/apache/accumulo/classloader/lcc/LocalCachingContextClassLoaderFactory.java
index 853a683..437352c 100644
--- 
a/modules/local-caching-classloader/src/main/java/org/apache/accumulo/classloader/lcc/LocalCachingContextClassLoaderFactory.java
+++ 
b/modules/local-caching-classloader/src/main/java/org/apache/accumulo/classloader/lcc/LocalCachingContextClassLoaderFactory.java
@@ -223,13 +223,8 @@ public class LocalCachingContextClassLoaderFactory 
implements ContextClassLoader
     } else {
       computedDefinition = previousDefinition;
     }
-    final URLClassLoader classloader = classloaders.computeIfAbsent(
-        new ContextCacheKey(contextLocation, computedDefinition), 
(Supplier<LocalStore>) () -> {
-          var s = localStore.get();
-          s.storeContextResources(computedDefinition);
-          return s;
-        });
-    resultHolder.set(classloader);
+    resultHolder.set(classloaders.computeIfAbsent(
+        new ContextCacheKey(contextLocation, computedDefinition), 
localStore::get));
     return computedDefinition;
   }
 
diff --git 
a/modules/local-caching-classloader/src/main/java/org/apache/accumulo/classloader/lcc/util/LccUtils.java
 
b/modules/local-caching-classloader/src/main/java/org/apache/accumulo/classloader/lcc/util/LccUtils.java
index 76bd939..39e363d 100644
--- 
a/modules/local-caching-classloader/src/main/java/org/apache/accumulo/classloader/lcc/util/LccUtils.java
+++ 
b/modules/local-caching-classloader/src/main/java/org/apache/accumulo/classloader/lcc/util/LccUtils.java
@@ -71,12 +71,16 @@ public class LccUtils {
     final var hardLinks = new LinkedHashSet<Path>();
     Path hardLinksDir = null;
 
+    var def = cacheKey.getContextDefinition();
+
+    // stage the downloads before attempting hard link creation
+    localStore.storeContextResources(def);
+
     // keep trying to hard-link all the resources if the hard-linking fails
     while (hardLinksDir == null) {
       hardLinks.clear();
       try {
-        hardLinksDir =
-            localStore.createWorkingHardLinks(cacheKey.getContextDefinition(), 
hardLinks::add);
+        hardLinksDir = localStore.createWorkingHardLinks(def, hardLinks::add);
         LOG.trace("Created hard links at {} for context {}", hardLinksDir, 
cacheKey);
       } catch (HardLinkFailedException e) {
         var failedHardLinksDir = e.getDestinationDirectory();
@@ -90,7 +94,7 @@ public class LccUtils {
               "Saw exception removing directory {} after hard link creation 
failure; this should be cleaned up manually",
               failedHardLinksDir, ioe);
         }
-        localStore.storeContextResources(cacheKey.getContextDefinition());
+        localStore.storeContextResources(def);
       }
     }
 
diff --git 
a/modules/local-caching-classloader/src/main/java/org/apache/accumulo/classloader/lcc/util/LocalStore.java
 
b/modules/local-caching-classloader/src/main/java/org/apache/accumulo/classloader/lcc/util/LocalStore.java
index d3243c8..bb8f809 100644
--- 
a/modules/local-caching-classloader/src/main/java/org/apache/accumulo/classloader/lcc/util/LocalStore.java
+++ 
b/modules/local-caching-classloader/src/main/java/org/apache/accumulo/classloader/lcc/util/LocalStore.java
@@ -214,7 +214,6 @@ public final class LocalStore {
 
     if (Files.exists(destinationPath)) {
       LOG.trace("Resource {} is already cached at {}", url, destinationPath);
-      verifyDownload(resource, destinationPath, null);
       try {
         // clean up any in progress files that may have been left behind by 
previous failed attempts
         Files.deleteIfExists(downloadingProgressPath);
@@ -348,17 +347,26 @@ public final class LocalStore {
   Path createWorkingHardLinks(final ContextDefinition contextDefinition, 
Consumer<Path> forEachLink)
       throws HardLinkFailedException {
     Path hardLinkDir = createTempDirectory("context-" + 
checksumForFileName(contextDefinition));
+    // create all hard links first
     for (Resource r : contextDefinition.getResources()) {
       String fileName = localResourceName(r);
       Path p = resourcesDir.resolve(fileName);
-      Path hardLink;
       try {
-        hardLink = Files.createLink(hardLinkDir.resolve(fileName), p);
+        Path hardLink = hardLinkDir.resolve(fileName);
+        LOG.trace("Creating hard link {} for resource {}", hardLink, 
r.getLocation());
+        Files.createLink(hardLink, p);
       } catch (NoSuchFileException e) {
         throw new HardLinkFailedException(hardLinkDir, p, e);
       } catch (IOException e) {
         throw new UncheckedIOException(e);
       }
+    }
+    // verify checksums
+    for (Resource r : contextDefinition.getResources()) {
+      String fileName = localResourceName(r);
+      Path hardLink = hardLinkDir.resolve(fileName);
+      LOG.trace("Verifying checksum of hard link {} for resource {}", 
hardLink, r.getLocation());
+      verifyDownload(r, hardLink, null);
       forEachLink.accept(hardLink);
     }
     return hardLinkDir;

Reply via email to