Better tentative fix for #24

This commit is contained in:
Blue (Lukas Rieger) 2020-03-28 16:25:38 +01:00
parent de7b0cba02
commit 62ce024dc6
3 changed files with 45 additions and 48 deletions

View File

@ -66,7 +66,10 @@ public void addRenderTask(RenderTask task) {
}
public RenderTicket createTicket(MapType mapType, Vector2i tile) {
RenderTicket ticket = new RenderTicket(mapType, tile);
return createTicket(new RenderTicket(mapType, tile));
}
private RenderTicket createTicket(RenderTicket ticket) {
synchronized (renderTickets) {
if (renderTicketMap.putIfAbsent(ticket, ticket) == null) {
renderTickets.add(ticket);
@ -138,7 +141,12 @@ private void renderThread() {
try {
ticket.render();
} catch (IOException e) {
Logger.global.logError("Failed to render tile " + ticket.getTile() + " of map '" + ticket.getMapType().getId() + "'!", e);
if (ticket.getRenderAttempts() < 3) {
Logger.global.logDebug("Failed to render tile " + ticket.getTile() + " of map '" + ticket.getMapType().getId() + "', rescheduling for " + (ticket.getRenderAttempts() + 1) + ". attempt..");
createTicket(ticket); //this might be a temporary issue, so we reschedule ticket for another attempt
} else {
Logger.global.logError("Failed to render tile " + ticket.getTile() + " of map '" + ticket.getMapType().getId() + "'!", e);
}
}
} else {
try {

View File

@ -10,15 +10,20 @@ public class RenderTicket {
private final MapType map;
private final Vector2i tile;
private int renderAttempts;
private boolean finished;
public RenderTicket(MapType map, Vector2i tile) {
this.map = map;
this.tile = tile;
this.renderAttempts = 0;
this.finished = false;
}
public synchronized void render() throws IOException {
renderAttempts++;
if (!finished) {
map.renderTile(tile);
@ -34,6 +39,10 @@ public Vector2i getTile() {
return tile;
}
public int getRenderAttempts() {
return renderAttempts;
}
public boolean isFinished() {
return finished;
}

View File

@ -218,57 +218,37 @@ private Chunk loadChunk(Vector2i chunkPos) throws IOException {
Vector2i regionPos = chunkToRegion(chunkPos);
Path regionPath = getMCAFilePath(regionPos);
Throwable exception = null;
try (RandomAccessFile raf = new RandomAccessFile(regionPath.toFile(), "r")) {
for (int tries = 1; tries <= 5; tries++) {
if (tries > 1) {
try {
Thread.sleep(200);
} catch (InterruptedException interrupt) {
throw new IOException("Interrupted while waiting for the " + tries + "th try to load a chunk..");
}
int xzChunk = Math.floorMod(chunkPos.getY(), 32) * 32 + Math.floorMod(chunkPos.getX(), 32);
raf.seek(xzChunk * 4);
int offset = raf.read() << 16;
offset |= (raf.read() & 0xFF) << 8;
offset |= raf.read() & 0xFF;
offset *= 4096;
int size = raf.readByte() * 4096;
if (size == 0) {
return Chunk.empty(this, chunkPos);
}
try (RandomAccessFile raf = new RandomAccessFile(regionPath.toFile(), "r")) {
raf.seek(offset + 4); // +4 skip chunk size
int xzChunk = Math.floorMod(chunkPos.getY(), 32) * 32 + Math.floorMod(chunkPos.getX(), 32);
byte compressionTypeByte = raf.readByte();
CompressionType compressionType = CompressionType.getFromID(compressionTypeByte);
if (compressionType == null) {
throw new IOException("invalid compression type " + compressionTypeByte);
}
raf.seek(xzChunk * 4);
int offset = raf.read() << 16;
offset |= (raf.read() & 0xFF) << 8;
offset |= raf.read() & 0xFF;
offset *= 4096;
int size = raf.readByte() * 4096;
if (size == 0) {
return Chunk.empty(this, chunkPos);
}
raf.seek(offset + 4); // +4 skip chunk size
byte compressionTypeByte = raf.readByte();
CompressionType compressionType = CompressionType.getFromID(compressionTypeByte);
if (compressionType == null) {
throw new IOException("invalid compression type " + compressionTypeByte);
}
DataInputStream dis = new DataInputStream(new BufferedInputStream(compressionType.decompress(new FileInputStream(raf.getFD()))));
Tag<?> tag = Tag.deserialize(dis, Tag.DEFAULT_MAX_DEPTH);
if (tag instanceof CompoundTag) {
return Chunk.create(this, (CompoundTag) tag);
} else {
throw new IOException("invalid data tag: " + (tag == null ? "null" : tag.getClass().getName()));
}
} catch (FileNotFoundException ex) {
return Chunk.empty(this, chunkPos);
} catch (Throwable ex) {
exception = ex;
DataInputStream dis = new DataInputStream(new BufferedInputStream(compressionType.decompress(new FileInputStream(raf.getFD()))));
Tag<?> tag = Tag.deserialize(dis, Tag.DEFAULT_MAX_DEPTH);
if (tag instanceof CompoundTag) {
return Chunk.create(this, (CompoundTag) tag);
} else {
throw new IOException("invalid data tag: " + (tag == null ? "null" : tag.getClass().getName()));
}
}
if (exception == null) throw new IOException("Failed to load chunk after multiple attempts!");
throw new IOException("Failed to load chunk after multiple attempts!", exception);
}
@Override