Skip to content

Commit e16516e

Browse files
authored
Full advisory locking (#167)
Implement full advisory locking, a side-struct which is used to coordinate, but do not lock the actual data we operate on, as some OS-es does not know to handle that. This means that Mimir now does not lock data it operates on, to make possible combining of features like exclusive access and cache purge on certain operating systems.
1 parent 2bf7646 commit e16516e

File tree

7 files changed

+37
-13
lines changed

7 files changed

+37
-13
lines changed

core/src/main/java/eu/maveniverse/maven/mimir/shared/SessionConfig.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ public interface SessionConfig {
8383

8484
Path basedir();
8585

86+
Path baseLocksDir();
87+
8688
Path propertiesPath();
8789

8890
Map<String, String> userProperties();
@@ -272,6 +274,7 @@ private static class Impl implements SessionConfig {
272274
private final boolean ignoreErrorAtSessionEnd;
273275
private final String mimirVersion;
274276
private final Path basedir;
277+
private final Path baseLocksDir;
275278
private final Path propertiesPath;
276279
private final Map<String, String> userProperties;
277280
private final Map<String, String> systemProperties;
@@ -301,6 +304,7 @@ private Impl(
301304
this.basedir = basedir == null
302305
? FileUtils.discoverBaseDirectory("mimir.basedir", ".mimir")
303306
: FileUtils.canonicalPath(basedir);
307+
this.baseLocksDir = this.basedir.resolve("locks");
304308
this.propertiesPath = propertiesPath == null
305309
? this.basedir.resolve("session.properties")
306310
: FileUtils.canonicalPath(this.basedir.resolve(propertiesPath));
@@ -382,6 +386,11 @@ public Path basedir() {
382386
return basedir;
383387
}
384388

389+
@Override
390+
public Path baseLocksDir() {
391+
return baseLocksDir;
392+
}
393+
385394
@Override
386395
public Path propertiesPath() {
387396
return propertiesPath;

daemon-slim/src/main/java/eu/maveniverse/maven/mimir/daemon/DaemonConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public class DaemonConfig {
2222
public static DaemonConfig with(SessionConfig sessionConfig) {
2323
requireNonNull(sessionConfig, "config");
2424

25-
Path daemonLockDir = sessionConfig.basedir().resolve("daemon");
25+
Path daemonLockDir = sessionConfig.baseLocksDir().resolve("daemon");
2626
Path socketPath = sessionConfig.basedir().resolve(Handle.DEFAULT_SOCKET_PATH);
2727
String systemNode = "file";
2828
boolean preSeedItself = false;

node/daemon/src/main/java/eu/maveniverse/maven/mimir/node/daemon/DaemonNodeConfig.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ public static DaemonNodeConfig with(SessionConfig sessionConfig) {
2727
.basedir()
2828
.resolve(sessionConfig.effectiveProperties().get("mimir.daemon.basedir")));
2929
}
30-
31-
Path daemonLockDir = daemonBasedir.resolve("daemon");
32-
Path daemonStarterLockDir = daemonBasedir.resolve("daemonStarter");
30+
// here we cannot use sessionConfig.baseLocksDir() as we may moved daemon basedir above
31+
Path locks = daemonBasedir.resolve("locks");
32+
Path daemonLockDir = locks.resolve("daemon");
33+
Path daemonStarterLockDir = locks.resolve("starter");
3334
Path socketPath = daemonBasedir.resolve(Handle.DEFAULT_SOCKET_PATH);
3435
Path daemonJavaHome = FileUtils.canonicalPath(daemonBasedir.resolve(sessionConfig
3536
.effectiveProperties()

node/file/src/main/java/eu/maveniverse/maven/mimir/node/file/FileNode.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
public final class FileNode extends NodeSupport implements SystemNode {
4949

5050
private final Path basedir;
51+
private final Path baseLockDir;
5152
private final boolean mayLink;
5253
private final boolean exclusiveAccess;
5354
private final FileNodeConfig.CachePurge cachePurge;
@@ -60,6 +61,7 @@ public final class FileNode extends NodeSupport implements SystemNode {
6061

6162
public FileNode(
6263
Path basedir,
64+
Path baseLockDir,
6365
boolean mayLink,
6466
boolean exclusiveAccess,
6567
FileNodeConfig.CachePurge cachePurge,
@@ -83,7 +85,9 @@ public FileNode(
8385
}
8486

8587
Files.createDirectories(basedir);
86-
this.directoryLocker.lockDirectory(basedir, exclusiveAccess);
88+
Files.createDirectories(baseLockDir);
89+
this.baseLockDir = baseLockDir;
90+
this.directoryLocker.lockDirectory(baseLockDir, exclusiveAccess);
8791

8892
// at this point, if cachePurge != OFF we have exclusiveAccess=true and we "own" exclusive lock over storage
8993
if (cachePurge == FileNodeConfig.CachePurge.OFF) {
@@ -253,7 +257,7 @@ protected void doClose() throws IOException {
253257
FileUtils.deleteRecursively(backup);
254258
}
255259
} finally {
256-
directoryLocker.unlockDirectory(basedir);
260+
directoryLocker.unlockDirectory(baseLockDir);
257261
}
258262
}
259263

node/file/src/main/java/eu/maveniverse/maven/mimir/node/file/FileNodeConfig.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public static FileNodeConfig with(SessionConfig sessionConfig) {
6363
requireNonNull(sessionConfig, "config");
6464

6565
Path basedir = sessionConfig.basedir().resolve("local");
66+
Path baseLockDir = sessionConfig.baseLocksDir().resolve(NAME);
6667
boolean mayLink = true;
6768
List<String> checksumAlgorithms = Arrays.asList("SHA-1", "SHA-512");
6869
String keyResolver = SimpleKeyResolverFactory.NAME;
@@ -95,28 +96,26 @@ public static FileNodeConfig with(SessionConfig sessionConfig) {
9596
cachePurge = CachePurge.valueOf(sessionConfig.effectiveProperties().get("mimir.file.cachePurge"));
9697
}
9798

98-
return new FileNodeConfig(basedir, mayLink, checksumAlgorithms, keyResolver, exclusiveAccess, cachePurge);
99+
return new FileNodeConfig(
100+
basedir, baseLockDir, mayLink, checksumAlgorithms, keyResolver, exclusiveAccess, cachePurge);
99101
}
100102

101103
public static FileNodeConfig of(
102104
Path basedir,
105+
Path baseLockDir,
103106
boolean mayLink,
104107
List<String> checksumAlgorithms,
105108
String keyResolver,
106109
boolean exclusiveAccess,
107110
CachePurge cachePurge) {
108111
return new FileNodeConfig(
109-
FileUtils.canonicalPath(basedir),
110-
mayLink,
111-
checksumAlgorithms,
112-
keyResolver,
113-
exclusiveAccess,
114-
cachePurge);
112+
basedir, baseLockDir, mayLink, checksumAlgorithms, keyResolver, exclusiveAccess, cachePurge);
115113
}
116114

117115
public static final String NAME = "file";
118116

119117
private final Path basedir;
118+
private final Path baseLockDir;
120119
private final boolean mayLink;
121120
private final List<String> checksumAlgorithms;
122121
private final String keyResolver;
@@ -125,12 +124,14 @@ public static FileNodeConfig of(
125124

126125
private FileNodeConfig(
127126
Path basedir,
127+
Path baseLockDir,
128128
boolean mayLink,
129129
List<String> checksumAlgorithms,
130130
String keyResolver,
131131
boolean exclusiveAccess,
132132
CachePurge cachePurge) {
133133
this.basedir = basedir;
134+
this.baseLockDir = baseLockDir;
134135
this.mayLink = mayLink;
135136
this.checksumAlgorithms = List.copyOf(checksumAlgorithms);
136137
this.keyResolver = keyResolver;
@@ -146,6 +147,10 @@ public Path basedir() {
146147
return basedir;
147148
}
148149

150+
public Path baseLockDir() {
151+
return baseLockDir;
152+
}
153+
149154
public boolean mayLink() {
150155
return mayLink;
151156
}

node/file/src/main/java/eu/maveniverse/maven/mimir/node/file/FileNodeFactory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public FileNode createSystemNode(SessionConfig sessionConfig) throws IOException
6262

6363
return new FileNode(
6464
fileNodeConfig.basedir(),
65+
fileNodeConfig.baseLockDir(),
6566
fileNodeConfig.mayLink(),
6667
fileNodeConfig.exclusiveAccess(),
6768
fileNodeConfig.cachePurge(),

node/jgroups/src/test/java/eu/maveniverse/maven/mimir/jgroups/JGroupsNodeTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ void smoke() throws Exception {
4343
Files.writeString(contentPath, content);
4444

4545
FileNodeConfig configOne = FileNodeConfig.of(
46+
one,
4647
one,
4748
true,
4849
Collections.singletonList("SHA-1"),
@@ -51,6 +52,7 @@ void smoke() throws Exception {
5152
FileNodeConfig.CachePurge.OFF);
5253
FileNode nodeOne = new FileNode(
5354
configOne.basedir(),
55+
configOne.baseLockDir(),
5456
configOne.mayLink(),
5557
configOne.exclusiveAccess(),
5658
configOne.cachePurge(),
@@ -59,6 +61,7 @@ void smoke() throws Exception {
5961
Map.of(Sha1ChecksumAlgorithmFactory.NAME, new Sha1ChecksumAlgorithmFactory()),
6062
DirectoryLocker.INSTANCE);
6163
FileNodeConfig configTwo = FileNodeConfig.of(
64+
two,
6265
two,
6366
true,
6467
Collections.singletonList("SHA-1"),
@@ -67,6 +70,7 @@ void smoke() throws Exception {
6770
FileNodeConfig.CachePurge.OFF);
6871
FileNode nodeTwo = new FileNode(
6972
configTwo.basedir(),
73+
configTwo.baseLockDir(),
7074
configTwo.mayLink(),
7175
configTwo.exclusiveAccess(),
7276
configTwo.cachePurge(),

0 commit comments

Comments
 (0)