Add delay-retry loop for handling temporarily locked image file writes

This commit is contained in:
Mike Primm 2011-06-20 16:58:07 -05:00
parent 6efbf3a3df
commit e584e3202b
3 changed files with 34 additions and 5 deletions

View File

@ -281,7 +281,7 @@ public class FlatMap extends MapType {
if(!outputFile.getParentFile().exists()) if(!outputFile.getParentFile().exists())
outputFile.getParentFile().mkdirs(); outputFile.getParentFile().mkdirs();
try { try {
ImageIO.write(im.buf_img, "png", outputFile); FileLockManager.imageIOWrite(im.buf_img, "png", outputFile);
} catch (IOException e) { } catch (IOException e) {
Debug.error("Failed to save image: " + outputFile.getPath(), e); Debug.error("Failed to save image: " + outputFile.getPath(), e);
} catch (java.lang.NullPointerException e) { } catch (java.lang.NullPointerException e) {
@ -308,7 +308,7 @@ public class FlatMap extends MapType {
if(!dayfile.getParentFile().exists()) if(!dayfile.getParentFile().exists())
dayfile.getParentFile().mkdirs(); dayfile.getParentFile().mkdirs();
try { try {
ImageIO.write(im_day.buf_img, "png", dayfile); FileLockManager.imageIOWrite(im_day.buf_img, "png", dayfile);
} catch (IOException e) { } catch (IOException e) {
Debug.error("Failed to save image: " + dayfile.getPath(), e); Debug.error("Failed to save image: " + dayfile.getPath(), e);
} catch (java.lang.NullPointerException e) { } catch (java.lang.NullPointerException e) {

View File

@ -265,7 +265,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
if(!fname.getParentFile().exists()) if(!fname.getParentFile().exists())
fname.getParentFile().mkdirs(); fname.getParentFile().mkdirs();
try { try {
ImageIO.write(img.buf_img, "png", fname); FileLockManager.imageIOWrite(img.buf_img, "png", fname);
} catch (IOException e) { } catch (IOException e) {
Debug.error("Failed to save image: " + fname.getPath(), e); Debug.error("Failed to save image: " + fname.getPath(), e);
} catch (java.lang.NullPointerException e) { } catch (java.lang.NullPointerException e) {
@ -291,7 +291,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
if(!dfname.getParentFile().exists()) if(!dfname.getParentFile().exists())
dfname.getParentFile().mkdirs(); dfname.getParentFile().mkdirs();
try { try {
ImageIO.write(img_day.buf_img, "png", dfname); FileLockManager.imageIOWrite(img_day.buf_img, "png", dfname);
} catch (IOException e) { } catch (IOException e) {
Debug.error("Failed to save image: " + dfname.getPath(), e); Debug.error("Failed to save image: " + dfname.getPath(), e);
} catch (java.lang.NullPointerException e) { } catch (java.lang.NullPointerException e) {
@ -365,7 +365,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
zoomFile.getParentFile().mkdirs(); zoomFile.getParentFile().mkdirs();
try { try {
ImageIO.write(zIm, "png", zoomFile); FileLockManager.imageIOWrite(zIm, "png", zoomFile);
Debug.debug("Saved zoom-out tile at " + zoomFile.getName()); Debug.debug("Saved zoom-out tile at " + zoomFile.getName());
} catch (IOException e) { } catch (IOException e) {
Debug.error("Failed to save zoom-out tile: " + zoomFile.getName(), e); Debug.error("Failed to save zoom-out tile: " + zoomFile.getName(), e);

View File

@ -1,6 +1,10 @@
package org.dynmap.utils; package org.dynmap.utils;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap; import java.util.HashMap;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.dynmap.Log; import org.dynmap.Log;
/** /**
@ -102,4 +106,29 @@ public class FileLockManager {
} }
//Log.info("releaseReadLock(" + f + ")"); //Log.info("releaseReadLock(" + f + ")");
} }
private static final int MAX_WRITE_RETRIES = 6;
/**
* Wrapper for IOImage.write - implements retries for busy files
*/
public static void imageIOWrite(BufferedImage img, String type, File fname) throws IOException {
int retrycnt = 0;
boolean done = false;
while(!done) {
try {
ImageIO.write(img, type, fname);
done = true;
} catch (FileNotFoundException fnfx) { /* This seems to be what we get when file is locked by reader */
if(retrycnt < MAX_WRITE_RETRIES) {
Log.info("Image file " + fname.getPath() + " - unable to write - retry #" + retrycnt);
try { Thread.sleep(50 << retrycnt); } catch (InterruptedException ix) { throw fnfx; }
retrycnt++;
}
else {
Log.info("Image file " + fname.getPath() + " - unable to write - failed");
throw fnfx;
}
}
}
}
} }