Skip to content

Commit 5e6c734

Browse files
Copilotrubensworks
andauthored
Fix script disk watcher registration for runtime and manual disk creation
Agent-Logs-Url: https://github.com/CyclopsMC/IntegratedScripting/sessions/36e2dd59-8157-4d69-b974-dbb9b29ccd47 Co-authored-by: rubensworks <440384+rubensworks@users.noreply.github.com>
1 parent 2f77eca commit 5e6c734

2 files changed

Lines changed: 91 additions & 0 deletions

File tree

src/main/java/org/cyclops/integratedscripting/core/network/ScriptingData.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,18 @@ public void initialize() {
105105
e.printStackTrace();
106106
}
107107

108+
// Register watcher for all disk directories
109+
try {
110+
WatchKey watchKey = disksPath.register(watchService,
111+
StandardWatchEventKinds.ENTRY_CREATE,
112+
StandardWatchEventKinds.ENTRY_MODIFY,
113+
StandardWatchEventKinds.ENTRY_DELETE);
114+
pathWatchers.put(disksPath, watchKey);
115+
pathWatchersReverse.put(watchKey, disksPath);
116+
} catch (IOException e) {
117+
e.printStackTrace();
118+
}
119+
108120
// Collect all disk ids
109121
List<Integer> diskIds = Lists.newArrayList();
110122
try {
@@ -248,6 +260,7 @@ public void setScripts(int disk, Map<Path, String> scripts, ChangeLocation chang
248260
}
249261

250262
// Register watchers for all directories
263+
this.registerPathWatcher(disk, null);
251264
for (Path path : scripts.keySet()) {
252265
this.registerPathWatcher(disk, path.getParent());
253266
}
@@ -366,6 +379,8 @@ protected void flushScript(int disk, Path scriptPathRelative) {
366379
} else {
367380
scriptPathAbsolute.getParent().toFile().mkdirs();
368381
FileUtils.write(scriptPathAbsolute.toFile(), script, StandardCharsets.UTF_8);
382+
this.registerPathWatcher(disk, null);
383+
this.registerPathWatcher(disk, scriptPathRelative.getParent());
369384
}
370385
} catch (IOException e) {
371386
e.printStackTrace();
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package org.cyclops.integratedscripting.core.network;
2+
3+
import org.apache.commons.io.FileUtils;
4+
import org.cyclops.integratedscripting.api.network.IScriptingData;
5+
import org.junit.Test;
6+
7+
import java.io.IOException;
8+
import java.nio.file.Files;
9+
import java.nio.file.Path;
10+
11+
import static org.hamcrest.CoreMatchers.equalTo;
12+
import static org.hamcrest.CoreMatchers.hasItem;
13+
import static org.junit.Assert.assertThat;
14+
import static org.junit.Assert.assertTrue;
15+
16+
public class ScriptingDataTest {
17+
18+
@Test
19+
public void testExternalUpdatesOnRuntimeCreatedDiskFolderAreSynced() throws IOException, InterruptedException {
20+
Path rootPath = Files.createTempDirectory("integratedscripting-test");
21+
ScriptingData scriptingData = new ScriptingData(rootPath);
22+
try {
23+
scriptingData.initialize();
24+
25+
Path diskPath = rootPath.resolve("scripting-disks").resolve("123");
26+
Files.createDirectories(diskPath);
27+
awaitCondition(() -> scriptingData.getDisks().contains(123));
28+
29+
Files.writeString(diskPath.resolve("main.js"), "export const value = 1;");
30+
awaitCondition(() -> "export const value = 1;".equals(scriptingData.getScripts(123).get(Path.of("main.js"))));
31+
32+
assertThat(scriptingData.getDisks(), hasItem(123));
33+
assertThat(scriptingData.getScripts(123).get(Path.of("main.js")), equalTo("export const value = 1;"));
34+
} finally {
35+
scriptingData.close();
36+
FileUtils.deleteDirectory(rootPath.toFile());
37+
}
38+
}
39+
40+
@Test
41+
public void testExternalUpdatesOnRuntimeFirstUsedDiskAreSynced() throws IOException, InterruptedException {
42+
Path rootPath = Files.createTempDirectory("integratedscripting-test");
43+
ScriptingData scriptingData = new ScriptingData(rootPath);
44+
try {
45+
scriptingData.initialize();
46+
47+
scriptingData.setScript(456, Path.of("main.js"), "export const value = 1;", IScriptingData.ChangeLocation.MEMORY);
48+
scriptingData.tick();
49+
assertTrue(Files.exists(rootPath.resolve("scripting-disks").resolve("456").resolve("main.js")));
50+
51+
Files.writeString(rootPath.resolve("scripting-disks").resolve("456").resolve("main.js"), "export const value = 2;");
52+
awaitCondition(() -> "export const value = 2;".equals(scriptingData.getScripts(456).get(Path.of("main.js"))));
53+
54+
assertThat(scriptingData.getScripts(456).get(Path.of("main.js")), equalTo("export const value = 2;"));
55+
} finally {
56+
scriptingData.close();
57+
FileUtils.deleteDirectory(rootPath.toFile());
58+
}
59+
}
60+
61+
private static void awaitCondition(Condition condition) throws InterruptedException {
62+
long deadline = System.currentTimeMillis() + 5000;
63+
while (System.currentTimeMillis() < deadline) {
64+
if (condition.matches()) {
65+
return;
66+
}
67+
Thread.sleep(25);
68+
}
69+
assertTrue("Timed out waiting for condition", condition.matches());
70+
}
71+
72+
@FunctionalInterface
73+
private interface Condition {
74+
boolean matches();
75+
}
76+
}

0 commit comments

Comments
 (0)