Add SIN.04028 tutorial material, tutor prompt and conversation log

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 15:11:02 +02:00
co-authored by Claude Opus 5
parent bac80295b7
commit f615bef426
30 changed files with 8123 additions and 0 deletions
@@ -0,0 +1,69 @@
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.concurrent.LinkedBlockingQueue;
record Route(String from, String to) {}
Route waitForRoute(String controlMailbox) throws InterruptedException {
var messages = new LinkedBlockingQueue<Message>();
var controlListener = Thread.ofVirtual().start(() -> {
try {
FileMessageBoard.watch(controlMailbox, messages::add);
} catch (InterruptedException _) {
Thread.currentThread().interrupt();
} catch (IOException exception) {
throw new UncheckedIOException(exception);
}
});
try {
while (true) {
var message = messages.take();
if (!message.type().equals("ROUTE")) {
IO.println("Ignored " + message.type() + "; expected ROUTE");
continue;
}
var mailboxes = message.value().lines().toList();
if (mailboxes.size() != 2
|| mailboxes.get(0).isBlank()
|| mailboxes.get(1).isBlank()) {
IO.println("ROUTE needs exactly two lines: <from> and <to>");
continue;
}
return new Route(mailboxes.get(0), mailboxes.get(1));
}
} finally {
controlListener.interrupt();
controlListener.join();
}
}
void main(String[] arguments) throws Exception {
if (arguments.length != 1
|| !arguments[0].matches("[A-Za-z0-9_-]+")) {
IO.println("Usage: java ConfigurableMediator.java <mediator-name>");
return;
}
var name = arguments[0];
var controlMailbox = "mediators/" + name + "/inbox";
IO.println(name + " waits for ROUTE on " + controlMailbox);
var route = waitForRoute(controlMailbox);
IO.println(name + " mediates: " + route.from() + " -> " + route.to());
FileMessageBoard.watch(route.from(), message -> {
try {
FileMessageBoard.publish(route.to(), message);
} catch (IOException exception) {
throw new UncheckedIOException(exception);
}
});
}