Skip to content
This repository has been archived by the owner on Apr 22, 2021. It is now read-only.

Commit

Permalink
Feature: add session data consumption information in GUI/text UIs (#287)
Browse files Browse the repository at this point in the history
* Feature: add session data consumption information in GUI/text UIs

Adds the total bytes downloaded and uploaded in the current session as well as the average data transfer rate for both UL/DL. The information is not added to the 1-line UI as the line will take 150+ characters in the screen.
  • Loading branch information
luguina authored Sep 12, 2020
1 parent 83ab21b commit 17d45f6
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 10 deletions.
4 changes: 2 additions & 2 deletions src/com/sheepit/client/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ protected void sendError(int step_, Job job_to_reset_, Error.Type error) {
args += "&extras=" + job_to_reset_.getExtras();
}
}
this.server.HTTPSendFile(this.server.getPage("error") + args, temp_file.getAbsolutePath(), step_);
this.server.HTTPSendFile(this.server.getPage("error") + args, temp_file.getAbsolutePath(), step_, this.gui);
temp_file.delete();
}
catch (Exception e) {
Expand Down Expand Up @@ -938,7 +938,7 @@ protected Error.Type confirmJob(Job ajob, int checkpoint) {
Type confirmJobReturnCode = Error.Type.OK;
retryLoop:
while (nb_try < max_try && ret != ServerCode.OK) {
ret = this.server.HTTPSendFile(url_real, ajob.getOutputImagePath(), checkpoint);
ret = this.server.HTTPSendFile(url_real, ajob.getOutputImagePath(), checkpoint, this.gui);
switch (ret) {
case OK:
// no issue, exit the loop
Expand Down
2 changes: 2 additions & 0 deletions src/com/sheepit/client/Gui.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public interface Gui {

public void setRenderingTime(String time_);

public void displayTransferStats(TransferStats downloads, TransferStats uploads);

public void displayStats(Stats stats);

public void displayUploadQueueStats(int queueSize, long queueVolume);
Expand Down
30 changes: 25 additions & 5 deletions src/com/sheepit/client/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
Expand Down Expand Up @@ -83,6 +85,9 @@ public class Server extends Thread {
private long lastRequestTime;
private int keepmealive_duration; // time in ms

private TransferStats dlStats = new TransferStats();
private TransferStats ulStats = new TransferStats();

public Server(String url_, Configuration user_config_, Client client_) {
super();
this.base_url = url_;
Expand Down Expand Up @@ -427,7 +432,6 @@ public Error.Type HTTPGetFile(String url_, String destination_, Gui gui_, String
return Error.Type.DOWNLOAD_FILE;
}

long start = new Date().getTime();
is = response.body().byteStream();
output = new FileOutputStream(destination_);

Expand All @@ -437,6 +441,8 @@ public Error.Type HTTPGetFile(String url_, String destination_, Gui gui_, String
long written = 0;
long lastUpd = 0; // last GUI progress update

LocalDateTime startRequestTime = LocalDateTime.now();

while ((len = is.read(buffer)) != -1) {
if (this.client.getRenderingJob().isServerBlockJob()) {
return Error.Type.RENDERER_KILLED_BY_SERVER;
Expand All @@ -454,10 +460,13 @@ else if (this.client.getRenderingJob().isUserBlockJob()) {
}
}

LocalDateTime endRequestTime = LocalDateTime.now();
Duration duration = Duration.between(startRequestTime, endRequestTime);
this.dlStats.calc(written, ((duration.getSeconds() * 1000) + (duration.getNano() / 1000000)));
gui_.displayTransferStats(dlStats, ulStats);
gui_.status(status_, 100, size);

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 bytes", (float) (size/1024) / duration.getSeconds(), written));
this.lastRequestTime = new Date().getTime();

return Error.Type.OK;
Expand Down Expand Up @@ -491,22 +500,33 @@ else if (this.client.getRenderingJob().isUserBlockJob()) {
return Error.Type.DOWNLOAD_FILE;
}

public ServerCode HTTPSendFile(String surl, String file1, int checkpoint) {
public ServerCode HTTPSendFile(String surl, String file1, int checkpoint, Gui gui) {
this.log.debug(checkpoint, "Server::HTTPSendFile(" + surl + "," + file1 + ")");

try {
String fileMimeType = Utils.findMimeType(file1);
File fileHandler = new File(file1);

MediaType MEDIA_TYPE = MediaType.parse(fileMimeType); // e.g. "image/png"

RequestBody uploadContent = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file", new File(file1).getName(), RequestBody.create(new File(file1), MEDIA_TYPE)).build();
.addFormDataPart("file", fileHandler.getName(), RequestBody.create(fileHandler, MEDIA_TYPE)).build();

Request request = new Request.Builder().addHeader("User-Agent", HTTP_USER_AGENT).url(surl).post(uploadContent).build();

LocalDateTime startRequestTime = LocalDateTime.now();

Call call = httpClient.newCall(request);
Response response = call.execute();

LocalDateTime endRequestTime = LocalDateTime.now();
Duration duration = Duration.between(startRequestTime, endRequestTime);

this.ulStats.calc(fileHandler.length(), ((duration.getSeconds() * 1000) + (duration.getNano() / 1000000)));
gui.displayTransferStats(dlStats, ulStats);

this.log.debug(String.format("File uploaded at %s/s, uploaded %d bytes", Utils.formatDataConsumption((long) fileHandler.length() / duration.getSeconds()), fileHandler.length()));

int r = response.code();
String contentType = response.body().contentType().toString();

Expand Down
36 changes: 36 additions & 0 deletions src/com/sheepit/client/TransferStats.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.sheepit.client;

import lombok.AllArgsConstructor;

/****************
* Holds the session traffic statistics. The constructor accepts two parameters:
* @long bytes - bytes transferred in the session
* @Job seconds - seconds spent transferring the data
*/
@AllArgsConstructor
public class TransferStats {
private long bytes;
private long millis;

public TransferStats() {
this.bytes = 0;
this.millis = 0;
}

public void calc(long bytes, long millis) {
this.bytes += bytes;
this.millis += millis;
}

public String getSessionTraffic() {
return Utils.formatDataConsumption(this.bytes);
}

public String getAverageSessionSpeed() {
try {
return Utils.formatDataConsumption((long) (this.bytes / (this.millis / 1000f)));
} catch (ArithmeticException e) { // Unlikely, but potential division by zero fallback if first transfer is done in zero millis
return Utils.formatDataConsumption((long) (this.bytes / (0.1f)));
}
}
}
20 changes: 20 additions & 0 deletions src/com/sheepit/client/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -228,4 +228,24 @@ public static String findMimeType(String file) throws IOException {

return mimeType;
}

public static String formatDataConsumption(long bytes) {
float divider = 0;
String suffix = "";

if (bytes > 1099511627776f) { // 1TB
divider = 1099511627776f;
suffix = "TB";
}
else if (bytes > 1073741824) { // 1GB
divider = 1073741824;
suffix = "GB";
}
else { // 1MB
divider = 1048576;
suffix = "MB";
}

return String.format("%.2f%s", (bytes / divider), suffix);
}
}
5 changes: 5 additions & 0 deletions src/com/sheepit/client/standalone/GuiSwing.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import com.sheepit.client.Gui;
import com.sheepit.client.SettingsLoader;
import com.sheepit.client.Stats;
import com.sheepit.client.TransferStats;
import com.sheepit.client.standalone.swing.activity.Settings;
import com.sheepit.client.standalone.swing.activity.Working;
import lombok.Getter;
Expand Down Expand Up @@ -223,6 +224,10 @@ else if (client.getConfiguration().getTheme().equals("dark")) {
}
}

@Override public synchronized void displayTransferStats(TransferStats downloads, TransferStats uploads) {
this.activityWorking.displayTransferStats(downloads, uploads);
}

@Override public void AddFrameRendered() {
framesRendered++;

Expand Down
7 changes: 7 additions & 0 deletions src/com/sheepit/client/standalone/GuiText.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.sheepit.client.Gui;
import com.sheepit.client.Log;
import com.sheepit.client.Stats;
import com.sheepit.client.TransferStats;
import com.sheepit.client.standalone.text.CLIInputActionHandler;
import com.sheepit.client.standalone.text.CLIInputObserver;

Expand Down Expand Up @@ -132,6 +133,12 @@ else if (client.isRunning() && client.isSuspended() == false) {
System.out.println(String.format("%s Frames rendered: %d", this.df.format(new Date()), this.framesRendered));
}

@Override public synchronized void displayTransferStats(TransferStats downloads, TransferStats uploads) {
System.out.println(String
.format("%s Session downloads: %s @ %s/s / Uploads: %s @ %s/s", this.df.format(new Date()), downloads.getSessionTraffic(),
downloads.getAverageSessionSpeed(), uploads.getSessionTraffic(), uploads.getAverageSessionSpeed()));
}

@Override public void displayStats(Stats stats) {
System.out.println(String.format("%s Frames remaining: %d", this.df.format(new Date()), stats.getRemainingFrame()));
System.out.println(String.format("%s Credits earned: %d", this.df.format(new Date()), stats.getCreditsEarnedDuringSession()));
Expand Down
5 changes: 5 additions & 0 deletions src/com/sheepit/client/standalone/GuiTextOneLine.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.sheepit.client.Client;
import com.sheepit.client.Gui;
import com.sheepit.client.Stats;
import com.sheepit.client.TransferStats;
import com.sheepit.client.standalone.text.CLIInputActionHandler;
import com.sheepit.client.standalone.text.CLIInputObserver;

Expand Down Expand Up @@ -154,6 +155,10 @@ else if (client.isRunning() && client.isSuspended() == false) {
updateLine();
}

@Override public synchronized void displayTransferStats(TransferStats downloads, TransferStats uploads) {
// Session traffic stats not shown in the 1 line UI to avoid increasing the line length above 120 chars
}

@Override public void displayStats(Stats stats) {
remaining = stats.getRemainingFrame();
creditsEarned = String.valueOf(stats.getCreditsEarnedDuringSession());
Expand Down
27 changes: 24 additions & 3 deletions src/com/sheepit/client/standalone/swing/activity/Working.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import com.sheepit.client.Job;
import com.sheepit.client.Log;
import com.sheepit.client.Stats;
import com.sheepit.client.TransferStats;
import com.sheepit.client.Utils;
import com.sheepit.client.standalone.GuiSwing;
import com.sheepit.client.standalone.GuiSwing.ActivityType;
Expand All @@ -75,6 +76,8 @@ public class Working implements Activity {
private JLabel connected_machines_value;
private JLabel user_info_total_rendertime_this_session_value;
private JLabel userInfoQueuedUploadsAndSizeValue;
private JLabel sessionDownloadsStatsValue;
private JLabel sessionUploadsStatsValue;
private String currentTheme;
private Log log;

Expand All @@ -97,6 +100,8 @@ public Working(GuiSwing parent_) {
lastRenderTime = new JLabel("");
lastRender = new JLabel("");
userInfoQueuedUploadsAndSizeValue = new JLabel("0");
sessionDownloadsStatsValue = new JLabel("0KB");
sessionUploadsStatsValue = new JLabel("0KB");
currentTheme = UIManager.getLookAndFeel().getName(); // Capture the theme on component instantiation
previousStatus = "";
log = Log.getInstance(parent_.getConfiguration());
Expand Down Expand Up @@ -126,6 +131,8 @@ public Working(GuiSwing parent_) {
lastRenderTime = new JLabel(lastRenderTime.getText());
lastRender = new JLabel(lastRender.getText());
userInfoQueuedUploadsAndSizeValue = new JLabel(userInfoQueuedUploadsAndSizeValue.getText());
sessionDownloadsStatsValue = new JLabel(sessionDownloadsStatsValue.getText());
sessionUploadsStatsValue = new JLabel(sessionUploadsStatsValue.getText());

// set the new theme as the current one
currentTheme = UIManager.getLookAndFeel().getName();
Expand Down Expand Up @@ -163,6 +170,8 @@ public Working(GuiSwing parent_) {
JLabel user_info_credits_this_session = new JLabel("Points earned: ", JLabel.TRAILING);
JLabel user_info_total_rendertime_this_session = new JLabel("Duration: ", JLabel.TRAILING);
JLabel user_info_pending_uploads_and_size = new JLabel("Queued uploads: ", JLabel.TRAILING);
JLabel session_download_stats = new JLabel("Total Downloads: ", JLabel.TRAILING);
JLabel session_upload_stats = new JLabel("Total Uploads: ", JLabel.TRAILING);
JLabel user_info_rendered_frame_this_session = new JLabel("Rendered frames: ", JLabel.TRAILING);
JLabel global_static_renderable_project = new JLabel("Renderable projects: ", JLabel.TRAILING);

Expand All @@ -175,6 +184,12 @@ public Working(GuiSwing parent_) {
session_info_panel.add(user_info_pending_uploads_and_size);
session_info_panel.add(userInfoQueuedUploadsAndSizeValue);

session_info_panel.add(session_download_stats);
session_info_panel.add(sessionDownloadsStatsValue);

session_info_panel.add(session_upload_stats);
session_info_panel.add(sessionUploadsStatsValue);

session_info_panel.add(global_static_renderable_project);
session_info_panel.add(renderable_projects_value);

Expand Down Expand Up @@ -260,10 +275,10 @@ public Working(GuiSwing parent_) {
widthLeftColumn = Spring.max(widthLeftColumn, getBestWidth(session_info_panel, 4, 2));
alignPanel(current_project_panel, 5, 2, widthLeftColumn);
alignPanel(global_stats_panel, 4, 2, widthLeftColumn);
alignPanel(session_info_panel, 5, 2, widthLeftColumn);
alignPanel(session_info_panel, 7, 2, widthLeftColumn);

// Set the proper size for the Working (if coming from Settings screen, the window size will be too big for the content!)
parent.setSize(520, 760);
parent.setSize(520, 820);
}

public void setStatus(String msg_) {
Expand Down Expand Up @@ -303,6 +318,12 @@ public void setComputeMethod(String computeMethod_) {
this.current_project_compute_method_value.setText(computeMethod_);
}

public void displayTransferStats(TransferStats downloads, TransferStats uploads) {
sessionDownloadsStatsValue.setText(String.format("%s @ %s/s", downloads.getSessionTraffic(), downloads.getAverageSessionSpeed()));
sessionUploadsStatsValue.setText(String.format("%s @ %s/s", uploads.getSessionTraffic(), uploads.getAverageSessionSpeed()));
updateTime();
}

public void displayStats(Stats stats) {
DecimalFormat df = new DecimalFormat("##,##,##,##,##,##,##0");
remainingFrameContent.setText(df.format(stats.getRemainingFrame()));
Expand Down Expand Up @@ -334,7 +355,7 @@ public void displayUploadQueueStats(int queueSize, long queueVolume) {
}
}

public void updateTime() {
public synchronized void updateTime() {
if (this.parent.getClient().getStartTime() != 0) {
user_info_total_rendertime_this_session_value
.setText(Utils.humanDuration(new Date((new Date().getTime() - this.parent.getClient().getStartTime()))));
Expand Down

0 comments on commit 17d45f6

Please sign in to comment.