Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public SubmittedBatch createIssue(final URI repository, final String body, final
}

@Override
public List<SubmissionReceipt> receipts(final URI repository, final SubmittedBatch batch) throws IOException {
public SubmissionStatus status(final URI repository, final SubmittedBatch batch) throws IOException {
final JsonArray comments = request("GET", endpoint(repository, "issues/" + batch.issueNumber()
+ "/comments?per_page=100"), null).getAsJsonArray("comments");
final List<SubmissionReceipt> receipts = new ArrayList<>();
Expand All @@ -61,7 +61,9 @@ public List<SubmissionReceipt> receipts(final URI repository, final SubmittedBat
receipts.addAll(receipts(body.getAsString(), batch.issueUrl()));
}
}
return receipts;
final JsonObject issue = request("GET", endpoint(repository, "issues/" + batch.issueNumber()), null);
final boolean terminal = "closed".equals(issue.get("state").getAsString());
return new SubmissionStatus(batch, receipts, terminal);
}

private JsonObject request(final String method, final URI endpoint, final String body) throws IOException {
Expand Down
31 changes: 20 additions & 11 deletions src/main/java/dev/robocode/rumble/client/IssueOpsSubmission.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@ final class IssueOpsSubmission {
}

SubmissionReport submit(final RankedJournal journal, final RumbleSnapshot snapshot) throws IOException {
final List<SubmissionReceipt> receipts = collectReceipts(journal.unacknowledgedSubmissions(), snapshot);
final List<SubmissionStatus> statuses = collectStatuses(journal.unacknowledgedSubmissions(), snapshot);
final List<SubmissionReceipt> receipts = statuses.stream().flatMap(status -> status.receipts().stream()).toList();
journal.acknowledge(receipts);
final Set<UUID> terminal = statuses.stream().filter(SubmissionStatus::terminal)
.flatMap(status -> status.batch().battleIds().stream()).collect(Collectors.toSet());
final Set<UUID> inFlight = journal.unacknowledgedSubmissions().stream().flatMap(batch -> batch.battleIds().stream())
.filter(battleId -> !terminal.contains(battleId))
.collect(Collectors.toSet());
final List<RankedBattleRecord> pending = journal.pending().stream().filter(record -> !inFlight.contains(record.battleId()))
.toList();
Expand All @@ -47,18 +51,16 @@ SubmissionReport submit(final RankedJournal journal, final RumbleSnapshot snapsh
return new SubmissionReport(receipts, submitted);
}

private List<SubmissionReceipt> collectReceipts(final List<SubmittedBatch> submitted,
final RumbleSnapshot snapshot) throws IOException {
final List<SubmissionReceipt> receipts = new ArrayList<>();
private List<SubmissionStatus> collectStatuses(final List<SubmittedBatch> submitted,
final RumbleSnapshot snapshot) throws IOException {
final List<SubmissionStatus> statuses = new ArrayList<>();
for (final SubmittedBatch batch : submitted) {
final Set<UUID> expected = Set.copyOf(batch.battleIds());
for (final SubmissionReceipt receipt : transport.receipts(snapshot.canonicalDataRepository(), batch)) {
if (expected.contains(receipt.battleId())) {
receipts.add(receipt);
}
}
final SubmissionStatus status = transport.status(snapshot.canonicalDataRepository(), batch);
statuses.add(new SubmissionStatus(batch, status.receipts().stream()
.filter(receipt -> expected.contains(receipt.battleId())).toList(), status.terminal()));
}
return receipts;
return statuses;
}

private static List<List<RankedBattleRecord>> batches(final List<RankedBattleRecord> records) {
Expand Down Expand Up @@ -110,5 +112,12 @@ record SubmissionReport(List<SubmissionReceipt> receipts, List<SubmittedBatch> s
interface IssueOpsTransport {
SubmittedBatch createIssue(URI repository, String body, String title) throws IOException;

List<SubmissionReceipt> receipts(URI repository, SubmittedBatch batch) throws IOException;
SubmissionStatus status(URI repository, SubmittedBatch batch) throws IOException;
}

/** One observed issue state, including its durable accepted-record receipts. */
record SubmissionStatus(SubmittedBatch batch, List<SubmissionReceipt> receipts, boolean terminal) {
SubmissionStatus {
receipts = List.copyOf(receipts);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,33 @@ public SubmittedBatch createIssue(final URI repository, final String body, final
}

@Override
public List<SubmissionReceipt> receipts(final URI repository, final SubmittedBatch batch) {
return List.of();
public SubmissionStatus status(final URI repository, final SubmittedBatch batch) {
return new SubmissionStatus(batch, List.of(), false);
}
};

assertThrows(IOException.class, () -> new IssueOpsSubmission(unavailable, Clock.systemUTC()).submit(journal, snapshot()));
assertEquals(List.of(record), journal.pending());
}

@Test
@Tag("RCL-006")
void testRCL006_IntegrationNegative_terminallyRejectedBatchIsRetried() throws IOException {
final RankedBattleRecord record = record("676b8646-5993-4b60-9a1e-6112530d1e8d");
final RankedJournal journal = new RankedJournal(temporaryDirectory);
journal.append(record);
journal.recordSubmission(new SubmittedBatch(42, "https://github.com/example/rumble-data/issues/42",
List.of(record.battleId())));
final TerminalRejectionTransport transport = new TerminalRejectionTransport(record.battleId());

final SubmissionReport report = new IssueOpsSubmission(transport, Clock.systemUTC()).submit(journal, snapshot());

assertEquals(1, report.submitted().size());
assertEquals(1, transport.bodies.size());
assertTrue(transport.bodies.get(0).contains(record.battleId().toString()));
assertEquals(List.of(record), journal.pending());
}

@Test
@Tag("RCL-007")
void testRCL007_IntegrationPositive_splitsSixtyOneRecordsAcrossBoundedIssueBatches() throws IOException {
Expand Down Expand Up @@ -121,8 +139,8 @@ public SubmittedBatch createIssue(final URI repository, final String body, final
}

@Override
public List<SubmissionReceipt> receipts(final URI repository, final SubmittedBatch batch) {
return List.of(new SubmissionReceipt(accepted, batch.issueUrl()));
public SubmissionStatus status(final URI repository, final SubmittedBatch batch) {
return new SubmissionStatus(batch, List.of(new SubmissionReceipt(accepted, batch.issueUrl())), false);
}
}

Expand All @@ -137,8 +155,28 @@ public SubmittedBatch createIssue(final URI repository, final String body, final
}

@Override
public List<SubmissionReceipt> receipts(final URI repository, final SubmittedBatch batch) {
return List.of();
public SubmissionStatus status(final URI repository, final SubmittedBatch batch) {
return new SubmissionStatus(batch, List.of(), false);
}
}

private static final class TerminalRejectionTransport implements IssueOpsTransport {
private final UUID battleId;
private final List<String> bodies = new ArrayList<>();

private TerminalRejectionTransport(final UUID battleId) {
this.battleId = battleId;
}

@Override
public SubmittedBatch createIssue(final URI repository, final String body, final String title) {
bodies.add(body);
return new SubmittedBatch(43, "https://github.com/example/rumble-data/issues/43", List.of(battleId));
}

@Override
public SubmissionStatus status(final URI repository, final SubmittedBatch batch) {
return new SubmissionStatus(batch, List.of(), batch.issueNumber() == 42);
}
}
}
Loading