I am working on a scenario where I am reading files in a directory and then creating a zip file. But this operation sometimes blocks the Vertx thread and I received the following exception in Vertx trace:
021-06-01 14:46:22.533 io.vertx.core.impl.BlockedThreadChecker [WARNING] Thread Thread[vert.x-eventloop-thread-4,5,main]=Thread[vert.x-eventloop-thread-4,5,main] has been blocked for 65088 ms, time limit is 2000 ms
io.vertx.core.VertxException: Thread blocked
at java.util.zip.Deflater.deflateBytes(Native Method)
at java.util.zip.Deflater.deflate(Deflater.java:444)
at java.util.zip.Deflater.deflate(Deflater.java:366)
at java.util.zip.DeflaterOutputStream.deflate(DeflaterOutputStream.java:251)
at java.util.zip.DeflaterOutputStream.write(DeflaterOutputStream.java:211)
at java.util.zip.ZipOutputStream.write(ZipOutputStream.java:331)
Following is my method for creating a zip file
private String zipDirectory(File dir, String zipDirName) {
_log.info("Entered zip file utility2");
String zipFilePath;
try(FileOutputStream fos = new FileOutputStream(zipDirName);
ZipOutputStream zos = new ZipOutputStream(fos);) {
populateFilesList(dir);
for(String filePath : _filesListInDir){
_log.info("FILES: "+filePath);
File file = new File(filePath);
if(!"zip".equals(Files.getFileExtension(file.getName()))) {
ZipEntry ze = new ZipEntry(filePath.substring(dir.getAbsolutePath().length()+1, filePath.length()));
zos.putNextEntry(ze);
FileInputStream fis = new FileInputStream(filePath);
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
zos.flush();
zos.closeEntry();
fis.close();
}else {
_log.info("Ignore zip for writing");
}
}
Path zipFilePathDir = Paths.get(zipDirName);
zipFilePath = zipFilePathDir.getFileName().toString();
_log.info("Zip file name: "+zipFilePath);
zos.close();
fos.close();
} catch (IOException e) {
zipFilePath = "FAILURE";
_log.error("Error creating zip file: "+e.getMessage());
}
return zipFilePath;
}
Can anyone provide any suggestion as how can I make sure that I dont block the main event loop on Vertx
You can use
Vertx.executeBlocking
to run the method in a worker pool managed by Vert.x:If your method needs to block for more than 5 or 10 seconds, you may also want to create your own dedicated ThreadPool just for executing that method, which Vert.x calls a
WorkerExecutor
, and useWorkerExecutor.executeBlocking
instead.