mirror of
https://github.com/apache/maven-mvnd.git
synced 2025-09-10 21:22:03 +00:00
Merge pull request #439 from gnodet/i432
Attempt to fix bad registry errors, fixes #432 and #433
This commit is contained in:
@@ -16,9 +16,9 @@
|
||||
|
||||
package org.mvndaemon.mvnd.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.MappedByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileLock;
|
||||
@@ -139,6 +139,10 @@ public class DaemonRegistry implements AutoCloseable {
|
||||
|
||||
public List<DaemonStopEvent> getStopEvents() {
|
||||
read();
|
||||
return doGetDaemonStopEvents();
|
||||
}
|
||||
|
||||
protected List<DaemonStopEvent> doGetDaemonStopEvents() {
|
||||
return new ArrayList<>(stopEvents);
|
||||
}
|
||||
|
||||
@@ -242,12 +246,28 @@ public class DaemonRegistry implements AutoCloseable {
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Could not lock offset 0 of " + registryFile);
|
||||
} catch (IllegalStateException | ArrayIndexOutOfBoundsException e) {
|
||||
String absPath = registryFile.toAbsolutePath().normalize().toString();
|
||||
LOGGER.warn("Invalid daemon registry info, " +
|
||||
"trying to recover from this issue. " +
|
||||
"If you keep getting this warning, " +
|
||||
"try deleting the `registry.bin` file at [" + absPath + "]", e);
|
||||
this.reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Could not lock " + registryFile + " within " + LOCK_TIMEOUT_MS + " ms");
|
||||
}
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
infosMap.clear();
|
||||
stopEvents.clear();
|
||||
BufferCaster.cast(buffer).clear();
|
||||
buffer.putInt(0); // reset daemon count
|
||||
buffer.putInt(0); // reset stop event count
|
||||
}
|
||||
|
||||
private static final int PROCESS_ID = getProcessId0();
|
||||
|
||||
private static int getProcessId0() {
|
||||
@@ -271,7 +291,7 @@ public class DaemonRegistry implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
private String readString() {
|
||||
protected String readString() {
|
||||
int sz = buffer.getShort();
|
||||
if (sz == -1) {
|
||||
return null;
|
||||
@@ -284,16 +304,26 @@ public class DaemonRegistry implements AutoCloseable {
|
||||
return new String(buf, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
private void writeString(String str) {
|
||||
protected void writeString(String str) {
|
||||
if (str == null) {
|
||||
buffer.putShort((short) -1);
|
||||
} else if (str.length() > 1024) {
|
||||
throw new IllegalStateException("String too long: " + str);
|
||||
} else {
|
||||
byte[] buf = str.getBytes(StandardCharsets.UTF_8);
|
||||
buffer.putShort((short) buf.length);
|
||||
buffer.put(buf);
|
||||
return;
|
||||
}
|
||||
byte[] buf = str.getBytes(StandardCharsets.UTF_8);
|
||||
if (buf.length > 1024) {
|
||||
LOGGER.warn("Attempting to write string longer than 1024 bytes: '{}'. Please raise an issue.", str);
|
||||
str = str.substring(0, 1033);
|
||||
while (buf.length > 1024) {
|
||||
str = str.substring(0, str.length() - 12) + "…";
|
||||
buf = str.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
buffer.putShort((short) buf.length);
|
||||
buffer.put(buf);
|
||||
}
|
||||
|
||||
protected ByteBuffer buffer() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
@@ -17,6 +17,8 @@ package org.mvndaemon.mvnd.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
@@ -50,7 +52,53 @@ public class DaemonRegistryTest {
|
||||
assertNotNull(reg2.getAll());
|
||||
assertEquals(1, reg2.getAll().size());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecovery() throws IOException {
|
||||
Path temp = File.createTempFile("reg", ".data").toPath();
|
||||
temp.toFile().deleteOnExit();
|
||||
try (TestDaemonRegistry reg1 = new TestDaemonRegistry(temp)) {
|
||||
// first store daemon
|
||||
byte[] token = new byte[16];
|
||||
new Random().nextBytes(token);
|
||||
reg1.store(new DaemonInfo("12345678", "/java/home/",
|
||||
"/data/reg/", 0x12345678, 7502, token,
|
||||
Locale.getDefault().toLanguageTag(), Arrays.asList("-Xmx"),
|
||||
DaemonState.Idle, System.currentTimeMillis(), System.currentTimeMillis()));
|
||||
assertEquals(1, reg1.getAll().size());
|
||||
// store an invalid event to trigger recovery
|
||||
StringBuilder sb = new StringBuilder(1024);
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
sb.append('…');
|
||||
}
|
||||
reg1.storeStopEvent(new DaemonStopEvent("11111",
|
||||
System.currentTimeMillis(),
|
||||
DaemonExpirationStatus.QUIET_EXPIRE,
|
||||
sb.toString()));
|
||||
assertEquals(1, reg1.doGetDaemonStopEvents().size());
|
||||
// check if registry is reset
|
||||
assertEquals(0, reg1.getAll().size());
|
||||
assertEquals(0, reg1.doGetDaemonStopEvents().size());
|
||||
}
|
||||
}
|
||||
|
||||
static class TestDaemonRegistry extends DaemonRegistry {
|
||||
public TestDaemonRegistry(Path registryFile) {
|
||||
super(registryFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeString(String str) {
|
||||
ByteBuffer buffer = buffer();
|
||||
if (str == null) {
|
||||
buffer.putShort((short) -1);
|
||||
} else {
|
||||
byte[] buf = str.getBytes(StandardCharsets.UTF_8);
|
||||
buffer.putShort((short) buf.length);
|
||||
buffer.put(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user