Skip to content
This repository was archived by the owner on Apr 10, 2024. It is now read-only.

Commit 41b5bec

Browse files
authored
improve: parallel builds jvm locks and object list improvements (#84)
1 parent dfb972a commit 41b5bec

File tree

4 files changed

+48
-113
lines changed

4 files changed

+48
-113
lines changed

core/src/main/java/io/javaoperatorsdk/jenvtest/binary/BinaryDownloader.java

+13-14
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import java.io.FileInputStream;
66
import java.io.IOException;
77
import java.nio.file.Files;
8+
import java.util.Map;
9+
import java.util.concurrent.ConcurrentHashMap;
10+
import java.util.concurrent.locks.ReentrantLock;
811
import java.util.stream.Collectors;
912
import java.util.stream.Stream;
1013

@@ -17,7 +20,6 @@
1720
import io.javaoperatorsdk.jenvtest.JenvtestException;
1821
import io.javaoperatorsdk.jenvtest.Utils;
1922
import io.javaoperatorsdk.jenvtest.binary.repo.BinaryRepo;
20-
import io.javaoperatorsdk.jenvtest.lock.LockFile;
2123

2224
public class BinaryDownloader {
2325

@@ -28,6 +30,7 @@ public class BinaryDownloader {
2830
private final String jenvtestDir;
2931
private final BinaryRepo binaryRepo;
3032
private final OSInfo osInfoProvider;
33+
private static final Map<String, ReentrantLock> versionLocks = new ConcurrentHashMap<>();
3134

3235
public BinaryDownloader(String jenvtestDir, OSInfo osInfoProvider) {
3336
this.jenvtestDir = jenvtestDir;
@@ -42,31 +45,27 @@ public BinaryDownloader(String jenvtestDir, OSInfo osInfoProvider) {
4245
}
4346

4447
public File download(String version) {
45-
log.info("Downloading binaries with version: {}", version);
46-
var downloadDir = new File(jenvtestDir, BinaryManager.BINARY_LIST_DIR);
47-
downloadDir.mkdirs();
48-
LockFile lock =
49-
new LockFile(version + ".lock", downloadDir.getPath());
48+
var lock = versionLocks.computeIfAbsent(version, v -> new ReentrantLock());
5049
var dirForVersion = dirForVersion(version);
51-
if (lock.tryLock()) {
50+
lock.lock();
51+
try {
5252
if (dirForVersion.exists()) {
5353
return dirForVersion;
5454
}
55+
new File(jenvtestDir, BinaryManager.BINARY_LIST_DIR).mkdirs();
56+
log.info("Downloading binaries with version: {}", version);
5557
var tempFile = binaryRepo.downloadVersionToTempFile(version);
5658
File dir = createDirForBinaries(version);
5759
extractFiles(tempFile, dir);
60+
log.debug("Binary downloaded and extracted");
5861
var deleted = tempFile.delete();
5962
if (!deleted) {
6063
log.warn("Unable to delete temp file: {}", tempFile.getPath());
6164
}
62-
lock.releaseLock();
63-
return dir;
64-
} else {
65-
log.debug("Waiting for lock to be deleted for version: {}", version);
66-
lock.waitUntilLockDeleted();
67-
log.debug("Lock deleted for version: {}", version);
68-
return dirForVersion;
65+
} finally {
66+
lock.unlock();
6967
}
68+
return dirForVersion;
7069
}
7170

7271
public File downloadLatest() {

core/src/main/java/io/javaoperatorsdk/jenvtest/binary/repo/BinaryRepo.java

+26-16
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
import java.net.http.HttpClient;
88
import java.net.http.HttpRequest;
99
import java.net.http.HttpResponse;
10+
import java.util.List;
11+
import java.util.concurrent.locks.ReentrantLock;
12+
import java.util.stream.Collectors;
1013
import java.util.stream.Stream;
1114

1215
import org.apache.commons.io.FileUtils;
@@ -23,15 +26,14 @@ public class BinaryRepo {
2326

2427
private static final Logger log = LoggerFactory.getLogger(BinaryRepo.class);
2528

26-
private static final String BUCKET_NAME = "kubebuilder-tools";
27-
2829
private final OSInfo osInfo;
30+
private static List<String> objectNames;
31+
private static final ReentrantLock downloadLock = new ReentrantLock();
2932

3033
public BinaryRepo(OSInfo osInfo) {
3134
this.osInfo = osInfo;
3235
}
3336

34-
3537
public File downloadVersionToTempFile(String version) {
3638
try {
3739
String url = "https://storage.googleapis.com/kubebuilder-tools/kubebuilder-tools-" + version +
@@ -47,25 +49,33 @@ public File downloadVersionToTempFile(String version) {
4749
}
4850

4951
public Stream<String> listObjectNames() {
52+
downloadLock.lock();
5053
try {
51-
var httpClient = HttpClient.newBuilder()
52-
.build();
53-
54-
HttpRequest request = HttpRequest.newBuilder()
55-
.GET()
56-
.uri(URI.create("https://storage.googleapis.com/storage/v1/b/kubebuilder-tools/o"))
57-
.build();
58-
59-
var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()).body();
60-
ObjectMapper mapper =
61-
new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
62-
ObjectList objectList = mapper.readValue(response, ObjectList.class);
63-
return objectList.getItems().stream().map(ObjectListItem::getName);
54+
if (objectNames == null) {
55+
log.debug("Listing objects from storage");
56+
var httpClient = HttpClient.newBuilder()
57+
.build();
58+
59+
HttpRequest request = HttpRequest.newBuilder()
60+
.GET()
61+
.uri(URI.create("https://storage.googleapis.com/storage/v1/b/kubebuilder-tools/o"))
62+
.build();
63+
64+
var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()).body();
65+
ObjectMapper mapper =
66+
new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
67+
ObjectList objectList = mapper.readValue(response, ObjectList.class);
68+
objectNames = objectList.getItems().stream().map(ObjectListItem::getName)
69+
.collect(Collectors.toList());
70+
}
71+
return objectNames.stream();
6472
} catch (IOException e) {
6573
throw new JenvtestException(e);
6674
} catch (InterruptedException e) {
6775
Thread.currentThread().interrupt();
6876
throw new JenvtestException(e);
77+
} finally {
78+
downloadLock.unlock();
6979
}
7080
}
7181

core/src/main/java/io/javaoperatorsdk/jenvtest/cert/CertManager.java

+9-12
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.time.Instant;
1313
import java.time.temporal.ChronoUnit;
1414
import java.util.Date;
15+
import java.util.concurrent.locks.ReentrantLock;
1516

1617
import org.bouncycastle.asn1.x500.X500Name;
1718
import org.bouncycastle.asn1.x509.Extension;
@@ -28,7 +29,6 @@
2829
import org.slf4j.LoggerFactory;
2930

3031
import io.javaoperatorsdk.jenvtest.JenvtestException;
31-
import io.javaoperatorsdk.jenvtest.lock.LockFile;
3232

3333
public class CertManager {
3434

@@ -40,6 +40,8 @@ public class CertManager {
4040
public static final String CLIENT_KEY_NAME = "client.key";
4141
public static final String CLIENT_CERT_NAME = "client.crt";
4242

43+
private static final ReentrantLock generatorLock = new ReentrantLock();
44+
4345
private String jenvtestDir;
4446

4547
public CertManager(String jenvtestDir) {
@@ -50,20 +52,15 @@ public void createCertificatesIfNeeded() {
5052
if (certFilesPresent()) {
5153
return;
5254
}
53-
// locking is for parallel execution
54-
LockFile lockFile = new LockFile("cert.lock", jenvtestDir);
55-
if (lockFile.tryLock()) {
55+
generatorLock.lock();
56+
try {
5657
if (certFilesPresent()) {
5758
return;
5859
}
59-
try {
60-
generateAPIServerCertificates();
61-
generateUserCertificates();
62-
} finally {
63-
lockFile.releaseLock();
64-
}
65-
} else {
66-
lockFile.waitUntilLockDeleted();
60+
generateAPIServerCertificates();
61+
generateUserCertificates();
62+
} finally {
63+
generatorLock.unlock();
6764
}
6865
}
6966

core/src/main/java/io/javaoperatorsdk/jenvtest/lock/LockFile.java

-71
This file was deleted.

0 commit comments

Comments
 (0)