From 0508db7f753a5300be8dee3089b58a38d1e09c3a Mon Sep 17 00:00:00 2001 From: Laurent Clouet Date: Tue, 25 Apr 2017 13:06:23 +0200 Subject: [PATCH] User can choose how much he willing to spent on each frame (based on pull request from 'Rolf Aretz Lap' --- src/com/sheepit/client/Configuration.java | 10 ++++++ src/com/sheepit/client/Error.java | 1 + src/com/sheepit/client/Job.java | 31 +++++++++++++++++++ src/com/sheepit/client/Server.java | 2 +- src/com/sheepit/client/SettingsLoader.java | 19 +++++++++++- src/com/sheepit/client/standalone/Worker.java | 7 +++++ .../standalone/swing/activity/Settings.java | 25 +++++++++++++-- 7 files changed, 91 insertions(+), 4 deletions(-) diff --git a/src/com/sheepit/client/Configuration.java b/src/com/sheepit/client/Configuration.java index a30f9d7..1a4c8c8 100644 --- a/src/com/sheepit/client/Configuration.java +++ b/src/com/sheepit/client/Configuration.java @@ -48,6 +48,7 @@ public class Configuration { private int maxUploadingJob; private int nbCores; private int maxMemory; // max memory allowed for render + private int maxRenderTime; // max render time per frame allowed private int priority; private ComputeType computeMethod; private GPUDevice GPUDevice; @@ -66,6 +67,7 @@ public class Configuration { this.maxUploadingJob = 1; this.nbCores = -1; // ie not set this.maxMemory = -1; // ie not set + this.maxRenderTime = -1; // ie not set this.priority = 19; // default lowest this.computeMethod = null; this.GPUDevice = null; @@ -137,6 +139,14 @@ public class Configuration { return this.maxMemory; } + public void setMaxRenderTime(int max) { + this.maxRenderTime = max; + } + + public int getMaxRenderTime() { + return this.maxRenderTime; + } + public void setUsePriority(int priority) { if (priority > 19) priority = 19; diff --git a/src/com/sheepit/client/Error.java b/src/com/sheepit/client/Error.java index ef38693..c18e3af 100644 --- a/src/com/sheepit/client/Error.java +++ b/src/com/sheepit/client/Error.java @@ -40,6 +40,7 @@ public class Error { RENDERER_OUT_OF_MEMORY(21), RENDERER_KILLED(14), RENDERER_KILLED_BY_USER(20), + RENDERER_KILLED_BY_USER_OVER_TIME(23), RENDERER_KILLED_BY_SERVER(22), RENDERER_MISSING_LIBRARIES(15), FAILED_TO_EXECUTE(16), diff --git a/src/com/sheepit/client/Job.java b/src/com/sheepit/client/Job.java index 0d839a4..51db0b1 100644 --- a/src/com/sheepit/client/Job.java +++ b/src/com/sheepit/client/Job.java @@ -36,6 +36,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TimeZone; +import java.util.Timer; +import java.util.TimerTask; import com.sheepit.client.Configuration.ComputeType; import com.sheepit.client.Error.Type; @@ -224,6 +226,7 @@ public class Job { public Error.Type render() { gui.status("Rendering"); RenderProcess process = getProcessRender(); + Timer timerOfMaxRenderTime = null; String core_script = ""; if (getUseGPU() && config.getGPUDevice() != null && config.getComputeMethod() != ComputeType.CPU) { core_script = "sheepit_set_compute_device(\"CUDA\", \"GPU\", \"" + config.getGPUDevice().getCudaName() + "\")\n"; @@ -306,6 +309,24 @@ public class Job { getProcessRender().setProcess(os.exec(command, new_env)); BufferedReader input = new BufferedReader(new InputStreamReader(getProcessRender().getProcess().getInputStream())); + if (config.getMaxRenderTime() > 0) { + timerOfMaxRenderTime = new Timer(); + timerOfMaxRenderTime.schedule(new TimerTask() { + @Override + public void run() { + RenderProcess process = getProcessRender(); + if (process != null) { + long duration = (new Date().getTime() - process.getStartTime() ) / 1000; // in seconds + if (config.getMaxRenderTime() != -1 && duration > config.getMaxRenderTime()) { + log.debug("Killing render because process duration"); + OS.getOS().kill(process.getProcess()); + setAskForRendererKill(true); + } + } + } + }, config.getMaxRenderTime() * 1000 + 2000); // +2s to be sure the delay is over + } + long last_update_status = 0; log.debug("renderer output"); try { @@ -354,6 +375,9 @@ public class Job { int exit_value = process.exitValue(); process.finish(); + if (timerOfMaxRenderTime != null) { + timerOfMaxRenderTime.cancel(); + } if (script_file != null) { script_file.delete(); @@ -372,6 +396,13 @@ public class Job { if (getAskForRendererKill()) { log.debug("Job::render been asked to end render"); + + long duration = (new Date().getTime() - process.getStartTime() ) / 1000; // in seconds + if (config.getMaxRenderTime() != -1 && duration > config.getMaxRenderTime()) { + log.debug("Render killed because process duration (" + duration + "s) is over user setting (" + config.getMaxRenderTime() + "s)"); + return Error.Type.RENDERER_KILLED_BY_USER_OVER_TIME; + } + if (files.length != 0) { new File(files[0].getAbsolutePath()).delete(); } diff --git a/src/com/sheepit/client/Server.java b/src/com/sheepit/client/Server.java index d1048df..ab6b0c2 100644 --- a/src/com/sheepit/client/Server.java +++ b/src/com/sheepit/client/Server.java @@ -297,7 +297,7 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager HttpURLConnection connection = null; try { OS os = OS.getOS(); - String url = String.format("%s?computemethod=%s&cpu_cores=%s&ram_max=%s", this.getPage("request-job"), this.user_config.computeMethodToInt(), ((this.user_config.getNbCores() == -1) ? os.getCPU().cores() : this.user_config.getNbCores()), this.user_config.getMaxMemory()); + String url = String.format("%s?computemethod=%s&cpu_cores=%s&ram_max=%s&rendertime_max=%s", this.getPage("request-job"), this.user_config.computeMethodToInt(), ((this.user_config.getNbCores() == -1) ? os.getCPU().cores() : this.user_config.getNbCores()), this.user_config.getMaxMemory(), this.user_config.getMaxRenderTime()); if (this.user_config.getComputeMethod() != ComputeType.CPU && this.user_config.getGPUDevice() != null) { String gpu_model = ""; try { diff --git a/src/com/sheepit/client/SettingsLoader.java b/src/com/sheepit/client/SettingsLoader.java index 07df79b..293fec3 100644 --- a/src/com/sheepit/client/SettingsLoader.java +++ b/src/com/sheepit/client/SettingsLoader.java @@ -47,6 +47,7 @@ public class SettingsLoader { private String gpu; private String cores; private String ram; + private String renderTime; private String cacheDir; private String autoSignIn; private String ui; @@ -61,7 +62,7 @@ public class SettingsLoader { path = path_; } - public SettingsLoader(String login_, String password_, String proxy_, ComputeType computeMethod_, GPUDevice gpu_, int cores_, int maxRam_, String cacheDir_, boolean autoSignIn_, String ui_, String tileSize_, int priority_) { + public SettingsLoader(String login_, String password_, String proxy_, ComputeType computeMethod_, GPUDevice gpu_, int cores_, int maxRam_, int maxRenderTime_, String cacheDir_, boolean autoSignIn_, String ui_, String tileSize_, int priority_) { path = getDefaultFilePath(); login = login_; password = password_; @@ -77,6 +78,9 @@ public class SettingsLoader { if (maxRam_ > 0) { ram = String.valueOf(maxRam_); } + if (maxRenderTime_ > 0) { + renderTime = String.valueOf(maxRenderTime_); + } if (computeMethod_ != null) { try { computeMethod = computeMethod_.name(); @@ -125,6 +129,10 @@ public class SettingsLoader { prop.setProperty("ram", ram); } + if (renderTime != null) { + prop.setProperty("rendertime", renderTime); + } + if (login != null) { prop.setProperty("login", login); } @@ -193,6 +201,7 @@ public class SettingsLoader { this.tileSize = null; this.priority = 19; // must be the same default as Configuration this.ram = null; + this.renderTime = null; if (new File(path).exists() == false) { return; @@ -224,6 +233,10 @@ public class SettingsLoader { this.ram = prop.getProperty("ram"); } + if (prop.containsKey("rendertime")) { + this.renderTime = prop.getProperty("rendertime"); + } + if (prop.containsKey("login")) { this.login = prop.getProperty("login"); } @@ -315,6 +328,10 @@ public class SettingsLoader { config.setMaxMemory(Integer.valueOf(ram)); } + if (config.getMaxRenderTime() == -1 && renderTime != null) { + config.setMaxRenderTime(Integer.valueOf(renderTime)); + } + if (config.getUserSpecifiedACacheDir() == false && cacheDir != null && new File(cacheDir).exists()) { config.setCacheDir(new File(cacheDir)); } diff --git a/src/com/sheepit/client/standalone/Worker.java b/src/com/sheepit/client/standalone/Worker.java index 38e33d8..b3e18cc 100644 --- a/src/com/sheepit/client/standalone/Worker.java +++ b/src/com/sheepit/client/standalone/Worker.java @@ -70,6 +70,9 @@ public class Worker { @Option(name = "-memory", usage = "Maximum memory allow to be used by renderer (in MB)", required = false) private int max_ram = -1; + @Option(name = "-rendertime", usage = "Maximum time allow for each frame (in minute)", required = false) + private int max_rendertime = -1; + @Option(name = "--verbose", usage = "Display log", required = false) private boolean print_log = false; @@ -205,6 +208,10 @@ public class Worker { config.setMaxMemory(max_ram * 1000); } + if (max_rendertime > 0) { + config.setMaxRenderTime(max_rendertime * 60); + } + if (method != null) { try { compute_method = ComputeType.valueOf(method); diff --git a/src/com/sheepit/client/standalone/swing/activity/Settings.java b/src/com/sheepit/client/standalone/swing/activity/Settings.java index e15b445..98b8eba 100644 --- a/src/com/sheepit/client/standalone/swing/activity/Settings.java +++ b/src/com/sheepit/client/standalone/swing/activity/Settings.java @@ -44,7 +44,10 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JSlider; +import javax.swing.JSpinner; import javax.swing.JTextField; +import javax.swing.SpinnerNumberModel; + import com.sheepit.client.Configuration; import com.sheepit.client.Configuration.ComputeType; import com.sheepit.client.SettingsLoader; @@ -69,6 +72,7 @@ public class Settings implements Activity { private List useGPUs; private JSlider cpuCores; private JSlider ram; + private JSpinner renderTime; private JSlider priority; private JTextField proxy; @@ -303,7 +307,7 @@ public class Settings implements Activity { parent.getContentPane().add(compute_devices_panel, constraints); // other - JPanel advanced_panel = new JPanel(new GridLayout(3, 2)); + JPanel advanced_panel = new JPanel(new GridLayout(4, 2)); advanced_panel.setBorder(BorderFactory.createTitledBorder("Advanced options")); JLabel proxyLabel = new JLabel("Proxy:"); @@ -316,6 +320,17 @@ public class Settings implements Activity { advanced_panel.add(proxyLabel); advanced_panel.add(proxy); + + JLabel renderTimeLabel = new JLabel("Max time per frame (in minute):"); + int val = 0; + if (parent.getConfiguration().getMaxRenderTime() > 0) { + val = parent.getConfiguration().getMaxRenderTime() / 60; + } + renderTime = new JSpinner(new SpinnerNumberModel(val,0,1000,1)); + + advanced_panel.add(renderTimeLabel); + advanced_panel.add(renderTime); + JLabel customTileSizeLabel = new JLabel("Custom render tile size:"); customTileSize = new JCheckBox("", config.getTileSize() != -1); advanced_panel.add(customTileSizeLabel); @@ -533,6 +548,12 @@ public class Settings implements Activity { config.setMaxMemory(max_ram); } + int max_rendertime = -1; + if (renderTime != null) { + max_rendertime = (Integer)renderTime.getValue() * 60; + config.setMaxRenderTime(max_rendertime); + } + config.setUsePriority(priority.getValue()); String proxyText = null; @@ -572,7 +593,7 @@ public class Settings implements Activity { } if (saveFile.isSelected()) { - new SettingsLoader(login.getText(), new String(password.getPassword()), proxyText, method, selected_gpu, cpu_cores, max_ram, cachePath, autoSignIn.isSelected(), GuiSwing.type, tile, priority.getValue()).saveFile(); + new SettingsLoader(login.getText(), new String(password.getPassword()), proxyText, method, selected_gpu, cpu_cores, max_ram, max_rendertime, cachePath, autoSignIn.isSelected(), GuiSwing.type, tile, priority.getValue()).saveFile(); } else { try {