Fix: allow to cancel download by user or server initiated reset (#266)
This commit is contained in:
@@ -639,26 +639,26 @@ import lombok.Data;
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Error.Type work(final Job ajob) {
|
public Error.Type work(final Job ajob) {
|
||||||
int ret;
|
Error.Type downloadRet;
|
||||||
|
|
||||||
gui.setRenderingProjectName(ajob.getName());
|
gui.setRenderingProjectName(ajob.getName());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ret = this.downloadExecutable(ajob);
|
downloadRet = this.downloadExecutable(ajob);
|
||||||
if (ret != 0) {
|
if (downloadRet != Error.Type.OK) {
|
||||||
gui.setRenderingProjectName("");
|
gui.setRenderingProjectName("");
|
||||||
this.log.error("Client::work problem with downloadExecutable (ret " + ret + ")");
|
this.log.error("Client::work problem with downloadExecutable (ret " + downloadRet + ")");
|
||||||
return Error.Type.DOWNLOAD_FILE;
|
return downloadRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = this.downloadSceneFile(ajob);
|
downloadRet = this.downloadSceneFile(ajob);
|
||||||
if (ret != 0) {
|
if (downloadRet != Error.Type.OK) {
|
||||||
gui.setRenderingProjectName("");
|
gui.setRenderingProjectName("");
|
||||||
this.log.error("Client::work problem with downloadSceneFile (ret " + ret + ")");
|
this.log.error("Client::work problem with downloadSceneFile (ret " + downloadRet + ")");
|
||||||
return Error.Type.DOWNLOAD_FILE;
|
return downloadRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = this.prepareWorkingDirectory(ajob); // decompress renderer and scene archives
|
int ret = this.prepareWorkingDirectory(ajob); // decompress renderer and scene archives
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
gui.setRenderingProjectName("");
|
gui.setRenderingProjectName("");
|
||||||
this.log.error("Client::work problem with this.prepareWorkingDirectory (ret " + ret + ")");
|
this.log.error("Client::work problem with this.prepareWorkingDirectory (ret " + ret + ")");
|
||||||
@@ -716,36 +716,40 @@ import lombok.Data;
|
|||||||
return Error.Type.OK;
|
return Error.Type.OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int downloadSceneFile(Job ajob_) throws FermeExceptionNoSpaceLeftOnDevice {
|
protected Error.Type downloadSceneFile(Job ajob_) throws FermeExceptionNoSpaceLeftOnDevice {
|
||||||
return this.downloadFile(ajob_, ajob_.getSceneArchivePath(), ajob_.getSceneMD5(),
|
return this.downloadFile(ajob_, ajob_.getSceneArchivePath(), ajob_.getSceneMD5(),
|
||||||
String.format("%s?type=job&job=%s", this.server.getPage("download-archive"), ajob_.getId()), "project");
|
String.format("%s?type=job&job=%s", this.server.getPage("download-archive"), ajob_.getId()), "project");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int downloadExecutable(Job ajob) throws FermeExceptionNoSpaceLeftOnDevice {
|
protected Error.Type downloadExecutable(Job ajob) throws FermeExceptionNoSpaceLeftOnDevice {
|
||||||
return this.downloadFile(ajob, ajob.getRendererArchivePath(), ajob.getRendererMD5(),
|
return this.downloadFile(ajob, ajob.getRendererArchivePath(), ajob.getRendererMD5(),
|
||||||
String.format("%s?type=binary&job=%s", this.server.getPage("download-archive"), ajob.getId()), "renderer");
|
String.format("%s?type=binary&job=%s", this.server.getPage("download-archive"), ajob.getId()), "renderer");
|
||||||
}
|
}
|
||||||
|
|
||||||
private int downloadFile(Job ajob, String local_path, String md5_server, String url, String download_type) throws FermeExceptionNoSpaceLeftOnDevice {
|
private Error.Type downloadFile(Job ajob, String local_path, String md5_server, String url, String download_type) throws FermeExceptionNoSpaceLeftOnDevice {
|
||||||
File local_path_file = new File(local_path);
|
File local_path_file = new File(local_path);
|
||||||
String update_ui = "Downloading " + download_type;
|
String update_ui = "Downloading " + download_type;
|
||||||
|
|
||||||
if (local_path_file.exists() == true) {
|
if (local_path_file.exists() == true) {
|
||||||
this.gui.status("Reusing cached " + download_type);
|
this.gui.status("Reusing cached " + download_type);
|
||||||
return 0;
|
return Type.OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.gui.status(String.format("Downloading %s", download_type), 0, 0);
|
this.gui.status(String.format("Downloading %s", download_type), 0, 0);
|
||||||
|
|
||||||
// must download the archive
|
// must download the archive
|
||||||
int ret = this.server.HTTPGetFile(url, local_path, this.gui, update_ui);
|
Error.Type ret = this.server.HTTPGetFile(url, local_path, this.gui, update_ui);
|
||||||
|
|
||||||
|
if (ret != Type.RENDERER_KILLED_BY_SERVER || ret != Type.RENDERER_KILLED_BY_USER_OVER_TIME) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// Try to check the download file even if a download error has occurred (MD5 file check will delete the file if partially downloaded)
|
// Try to check the download file even if a download error has occurred (MD5 file check will delete the file if partially downloaded)
|
||||||
boolean md5_check = this.checkFile(ajob, local_path, md5_server);
|
boolean md5_check = this.checkFile(ajob, local_path, md5_server);
|
||||||
int attempts = 1;
|
int attempts = 1;
|
||||||
|
|
||||||
while ((ret != 0 || md5_check == false) && attempts < this.maxDownloadFileAttempts) {
|
while ((ret != Error.Type.OK || md5_check == false) && attempts < this.maxDownloadFileAttempts) {
|
||||||
if (ret != 0) {
|
if (ret != Error.Type.OK) {
|
||||||
this.gui.error(String.format("Unable to download %s (error %d). Retrying now", download_type, ret));
|
this.gui.error(String.format("Unable to download %s (error %d). Retrying now", download_type, ret));
|
||||||
this.log.debug("Client::downloadFile problem with Server.HTTPGetFile (return: " + ret + ") removing local file (path: " + local_path + ")");
|
this.log.debug("Client::downloadFile problem with Server.HTTPGetFile (return: " + ret + ") removing local file (path: " + local_path + ")");
|
||||||
}
|
}
|
||||||
@@ -758,18 +762,19 @@ import lombok.Data;
|
|||||||
this.log.debug("Client::downloadFile failed, let's try again (" + (attempts + 1) + "/" + this.maxDownloadFileAttempts + ") ...");
|
this.log.debug("Client::downloadFile failed, let's try again (" + (attempts + 1) + "/" + this.maxDownloadFileAttempts + ") ...");
|
||||||
|
|
||||||
ret = this.server.HTTPGetFile(url, local_path, this.gui, update_ui);
|
ret = this.server.HTTPGetFile(url, local_path, this.gui, update_ui);
|
||||||
|
|
||||||
md5_check = this.checkFile(ajob, local_path, md5_server);
|
md5_check = this.checkFile(ajob, local_path, md5_server);
|
||||||
attempts++;
|
attempts++;
|
||||||
|
|
||||||
if ((ret != 0 || md5_check == false) && attempts >= this.maxDownloadFileAttempts) {
|
if ((ret != Error.Type.OK || md5_check == false) && attempts >= this.maxDownloadFileAttempts) {
|
||||||
this.log.debug("Client::downloadFile failed after " + this.maxDownloadFileAttempts + " attempts, removing local file (path: " + local_path
|
this.log.debug("Client::downloadFile failed after " + this.maxDownloadFileAttempts + " attempts, removing local file (path: " + local_path
|
||||||
+ "), stopping...");
|
+ "), stopping...");
|
||||||
local_path_file.delete();
|
local_path_file.delete();
|
||||||
return -9;
|
return Type.DOWNLOAD_FILE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return Type.OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkFile(Job ajob, String local_path, String md5_server) {
|
private boolean checkFile(Job ajob, String local_path, String md5_server) {
|
||||||
|
|||||||
@@ -137,14 +137,16 @@ public class Server extends Thread {
|
|||||||
if (serverCode == ServerCode.KEEPMEALIVE_STOP_RENDERING) {
|
if (serverCode == ServerCode.KEEPMEALIVE_STOP_RENDERING) {
|
||||||
this.log.debug("Server::stayAlive server asked to kill local render process");
|
this.log.debug("Server::stayAlive server asked to kill local render process");
|
||||||
// kill the current process, it will generate an error but it's okay
|
// kill the current process, it will generate an error but it's okay
|
||||||
if (this.client != null && this.client.getRenderingJob() != null
|
if (this.client != null && this.client.getRenderingJob() != null) {
|
||||||
&& this.client.getRenderingJob().getProcessRender().getProcess() != null) {
|
|
||||||
this.client.getRenderingJob().setServerBlockJob(true);
|
this.client.getRenderingJob().setServerBlockJob(true);
|
||||||
|
|
||||||
|
if (this.client.getRenderingJob().getProcessRender().getProcess() != null) {
|
||||||
this.client.getRenderingJob().setAskForRendererKill(true);
|
this.client.getRenderingJob().setAskForRendererKill(true);
|
||||||
OS.getOS().kill(this.client.getRenderingJob().getProcessRender().getProcess());
|
OS.getOS().kill(this.client.getRenderingJob().getProcessRender().getProcess());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception e) { // for the read
|
catch (Exception e) { // for the read
|
||||||
this.log.debug("Server::stayAlive Exception " + e);
|
this.log.debug("Server::stayAlive Exception " + e);
|
||||||
}
|
}
|
||||||
@@ -414,19 +416,21 @@ public class Server extends Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int HTTPGetFile(String url_, String destination_, Gui gui_, String status_) throws FermeExceptionNoSpaceLeftOnDevice {
|
public Error.Type HTTPGetFile(String url_, String destination_, Gui gui_, String status_) throws FermeExceptionNoSpaceLeftOnDevice {
|
||||||
// the destination_ parent directory must exist
|
InputStream is = null;
|
||||||
|
OutputStream output = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Response response = this.HTTPRequest(url_);
|
Response response = this.HTTPRequest(url_);
|
||||||
|
|
||||||
if (response.code() != HttpURLConnection.HTTP_OK) {
|
if (response.code() != HttpURLConnection.HTTP_OK) {
|
||||||
this.log.error("Server::HTTPGetFile(" + url_ + ", ...) HTTP code is not " + HttpURLConnection.HTTP_OK + " it's " + response.code());
|
this.log.error("Server::HTTPGetFile(" + url_ + ", ...) HTTP code is not " + HttpURLConnection.HTTP_OK + " it's " + response.code());
|
||||||
return -1;
|
return Error.Type.DOWNLOAD_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
long start = new Date().getTime();
|
long start = new Date().getTime();
|
||||||
InputStream is = response.body().byteStream();
|
is = response.body().byteStream();
|
||||||
OutputStream output = new FileOutputStream(destination_);
|
output = new FileOutputStream(destination_);
|
||||||
|
|
||||||
long size = response.body().contentLength();
|
long size = response.body().contentLength();
|
||||||
byte[] buffer = new byte[8 * 1024];
|
byte[] buffer = new byte[8 * 1024];
|
||||||
@@ -435,6 +439,13 @@ public class Server extends Thread {
|
|||||||
long lastUpd = 0; // last GUI progress update
|
long lastUpd = 0; // last GUI progress update
|
||||||
|
|
||||||
while ((len = is.read(buffer)) != -1) {
|
while ((len = is.read(buffer)) != -1) {
|
||||||
|
if (this.client.getRenderingJob().isServerBlockJob()) {
|
||||||
|
return Error.Type.RENDERER_KILLED_BY_SERVER;
|
||||||
|
}
|
||||||
|
else if (this.client.getRenderingJob().isUserBlockJob()) {
|
||||||
|
return Error.Type.RENDERER_KILLED_BY_USER;
|
||||||
|
}
|
||||||
|
|
||||||
output.write(buffer, 0, len);
|
output.write(buffer, 0, len);
|
||||||
written += len;
|
written += len;
|
||||||
|
|
||||||
@@ -444,17 +455,13 @@ public class Server extends Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
output.flush();
|
|
||||||
output.close();
|
|
||||||
is.close();
|
|
||||||
|
|
||||||
gui_.status(status_, 100, size);
|
gui_.status(status_, 100, size);
|
||||||
|
|
||||||
long end = new Date().getTime();
|
long end = new Date().getTime();
|
||||||
this.log.debug(String.format("File downloaded at %.1f kB/s, written %d B", ((float) (size / 1000)) / ((float) (end - start) / 1000), written));
|
this.log.debug(String.format("File downloaded at %.1f kB/s, written %d B", ((float) (size / 1000)) / ((float) (end - start) / 1000), written));
|
||||||
this.lastRequestTime = new Date().getTime();
|
this.lastRequestTime = new Date().getTime();
|
||||||
|
|
||||||
return 0;
|
return Error.Type.OK;
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
if (Utils.noFreeSpaceOnDisk(new File(destination_).getParent())) {
|
if (Utils.noFreeSpaceOnDisk(new File(destination_).getParent())) {
|
||||||
@@ -465,8 +472,19 @@ public class Server extends Thread {
|
|||||||
e.printStackTrace(new PrintWriter(sw));
|
e.printStackTrace(new PrintWriter(sw));
|
||||||
this.log.error("Server::HTTPGetFile Exception " + e + " stacktrace " + sw.toString());
|
this.log.error("Server::HTTPGetFile Exception " + e + " stacktrace " + sw.toString());
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
output.flush();
|
||||||
|
output.close();
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
this.log.debug(String.format("Server::HTTPGetFile Error trying to close the open streams (%s)", e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.log.debug(String.format("Server::HTTPGetFile(%s) did fail", url_));
|
this.log.debug(String.format("Server::HTTPGetFile(%s) did fail", url_));
|
||||||
return -2;
|
return Error.Type.DOWNLOAD_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerCode HTTPSendFile(String surl, String file1, int checkpoint) {
|
public ServerCode HTTPSendFile(String surl, String file1, int checkpoint) {
|
||||||
|
|||||||
Reference in New Issue
Block a user