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;