Fixed mantle failure barriers

- Worker barriers propagate failed shared component tasks
- Cancelled shared tasks stop generation before later passes
- Local worktree directories remain excluded from source control
This commit is contained in:
Brian Neumann-Fopiano
2026-09-06 03:06:52 -04:00
parent 17c927acdd
commit 942545dcb9
3 changed files with 41 additions and 1 deletions
+2
View File
@@ -74,3 +74,5 @@ BUILDS/
# Version-content compat lane worktree. Generated, never source.
.compatwt/
.worktrees/
@@ -484,7 +484,11 @@ public interface MatterGenerator {
@Override
public boolean isReleasable() {
return task.future().isDone();
if (!task.future().isDone()) {
return false;
}
task.future().join();
return true;
}
}
@@ -21,8 +21,11 @@ import art.arcane.iris.util.common.parallel.MultiBurst;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -215,6 +218,37 @@ public class MatterGeneratorConcurrencyTest {
assertFalse(fixture.mantle.getChunk(0, 0).isFlagged(MantleFlag.PLANNED));
}
@Test
public void dispatcherPropagatesAnAlreadyFailedSharedComponent() {
IllegalStateException failure = new IllegalStateException("Shared component failed");
ExecutionException observed = sharedComponentFailure(CompletableFuture.failedFuture(failure), ExecutionException.class);
assertSame(failure, observed.getCause());
}
@Test
public void dispatcherPropagatesAnAlreadyCancelledSharedComponent() {
CompletableFuture<Void> cancelled = new CompletableFuture<>();
cancelled.cancel(false);
sharedComponentFailure(cancelled, CancellationException.class);
}
private <T extends Throwable> T sharedComponentFailure(CompletableFuture<Void> completion, Class<T> expectedFailure) {
GeneratorFixture fixture = new GeneratorFixture(true);
RecordingComponent component = new RecordingComponent(ReservedFlag.OBJECT, 0, 0);
TestMatterGenerator generator = fixture.generator(List.of(new MantlePass(List.of(component), 0, 0)));
MatterGenerator.MatterTaskKey key = new MatterGenerator.MatterTaskKey(fixture.mantle, 0, 0, ReservedFlag.OBJECT);
MatterGenerator.IN_FLIGHT_COMPONENTS.put(key, completion);
try {
CompletableFuture<Void> generation = MultiBurst.burst.completeValueAsync(() -> {
generator.generateMatter(0, 0, true, fixture.context);
return null;
});
return assertThrows(expectedFailure, () -> generation.get(5L, TimeUnit.SECONDS));
} finally {
MatterGenerator.IN_FLIGHT_COMPONENTS.remove(key, completion);
}
}
private static void await(CountDownLatch latch) {
try {
assertTrue(latch.await(5, TimeUnit.SECONDS));