Skip to content

Commit

Permalink
feat(youtube/return-youtube-dislike): debug connection statistics, to…
Browse files Browse the repository at this point in the history
…ast on error, high priority background threads (#236)

Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
  • Loading branch information
LisoUseInAIKyrios and oSumAtrIX committed Dec 21, 2022
1 parent 84377b2 commit 693ef08
Show file tree
Hide file tree
Showing 8 changed files with 394 additions and 108 deletions.
82 changes: 60 additions & 22 deletions app/src/main/java/app/revanced/integrations/requests/Requester.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,63 +26,101 @@ public static HttpURLConnection getConnectionFromRoute(String apiUrl, Route rout
}

/**
* Parse, and then disconnect the {@link HttpURLConnection}
*
* TODO: rename this to #parseJsonAndDisconnect
* Parse the {@link HttpURLConnection}, and closes the underlying InputStream.
*/
public static String parseJson(HttpURLConnection connection) throws IOException {
String result = parseJson(connection.getInputStream(), false);
return parseInputStreamAndClose(connection.getInputStream(), true);
}

/**
* Parse the {@link HttpURLConnection}, close the underlying InputStream, and disconnect.
*
* <b>Should only be used if other requests to the server are unlikely in the near future</b>
*
* @see #parseJson(HttpURLConnection)
*/
public static String parseJsonAndDisconnect(HttpURLConnection connection) throws IOException {
String result = parseJson(connection);
connection.disconnect();
return result;
}

/**
* Parse, and then close the {@link InputStream}
* Parse the {@link HttpURLConnection}, and closes the underlying InputStream.
*
* TODO: rename this to #parseJsonAndCloseStream
* @param stripNewLineCharacters if newline (\n) characters should be stripped from the InputStream
*/
public static String parseJson(InputStream inputStream, boolean isError) throws IOException {
public static String parseInputStreamAndClose(InputStream inputStream, boolean stripNewLineCharacters) throws IOException {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
StringBuilder jsonBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
jsonBuilder.append(line);
if (isError)
if (!stripNewLineCharacters)
jsonBuilder.append("\n");
}
return jsonBuilder.toString();
}
}

/**
* Parse, and then do NOT disconnect the {@link HttpURLConnection}
* Parse the {@link HttpURLConnection}, and closes the underlying InputStream.
*/
public static String parseErrorJson(HttpURLConnection connection) throws IOException {
// TODO: make this also disconnect, and rename method to #parseErrorJsonAndDisconnect
return parseJson(connection.getErrorStream(), true);
return parseInputStreamAndClose(connection.getErrorStream(), false);
}

/**
* Parse, and then disconnect the {@link HttpURLConnection}
* Parse the {@link HttpURLConnection}, close the underlying InputStream, and disconnect.
*
* TODO: rename this to #getJSONObjectAndDisconnect
* <b>Should only be used if other requests to the server are unlikely in the near future</b>
*
* @see #parseErrorJson(HttpURLConnection)
*/
public static JSONObject getJSONObject(HttpURLConnection connection) throws JSONException, IOException {
return new JSONObject(parseJsonAndDisconnect(connection));
public static String parseErrorJsonAndDisconnect(HttpURLConnection connection) throws IOException {
String result = parseErrorJson(connection);
connection.disconnect();
return result;
}

/**
* Parse, and then disconnect the {@link HttpURLConnection}
* Parse the {@link HttpURLConnection}, and closes the underlying InputStream.
*/
public static JSONObject parseJSONObject(HttpURLConnection connection) throws JSONException, IOException {
return new JSONObject(parseJson(connection));
}

/**
* Parse the {@link HttpURLConnection}, close the underlying InputStream, and disconnect.
*
* <b>Should only be used if other requests to the server are unlikely in the near future</b>
*
* TODO: rename this to #getJSONArrayAndDisconnect
* @see #parseJSONObject(HttpURLConnection)
*/
public static JSONObject parseJSONObjectAndDisconnect(HttpURLConnection connection) throws JSONException, IOException {
JSONObject object = parseJSONObject(connection);
connection.disconnect();
return object;
}

/**
* Parse the {@link HttpURLConnection}, and closes the underlying InputStream.
*/
public static JSONArray getJSONArray(HttpURLConnection connection) throws JSONException, IOException {
return new JSONArray(parseJsonAndDisconnect(connection));
public static JSONArray parseJSONArray(HttpURLConnection connection) throws JSONException, IOException {
return new JSONArray(parseJson(connection));
}

private static String parseJsonAndDisconnect(HttpURLConnection connection) throws IOException {
String json = parseJson(connection);
/**
* Parse the {@link HttpURLConnection}, close the underlying InputStream, and disconnect.
*
* <b>Should only be used if other requests to the server are unlikely in the near future</b>
*
* @see #parseJSONArray(HttpURLConnection)
*/
public static JSONArray parseJSONArrayAndDisconnect(HttpURLConnection connection) throws JSONException, IOException {
JSONArray array = parseJSONArray(connection);
connection.disconnect();
return json;
return array;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public class ReturnYouTubeDislike {
*/
private static final ExecutorService voteSerialExecutor = Executors.newSingleThreadExecutor();

// Must be volatile, since non-main threads read this field.
// Must be volatile, since this is read/write from different threads
private static volatile boolean isEnabled = SettingsEnum.RYD_ENABLED.getBoolean();

/**
Expand Down Expand Up @@ -138,11 +138,18 @@ public static void onComponentCreated(Object conversionContext, AtomicReference<
// Have to block the current thread until fetching is done
// There's no known way to edit the text after creation yet
RYDVoteData votingData;
long fetchStartTime = 0;
try {
votingData = getVoteFetchFuture().get(MILLISECONDS_TO_BLOCK_UI_WHILE_WAITING_FOR_DISLIKE_FETCH_TO_COMPLETE, TimeUnit.MILLISECONDS);
Future<RYDVoteData> fetchFuture = getVoteFetchFuture();
if (SettingsEnum.DEBUG.getBoolean() && !fetchFuture.isDone()) {
fetchStartTime = System.currentTimeMillis();
}
votingData = fetchFuture.get(MILLISECONDS_TO_BLOCK_UI_WHILE_WAITING_FOR_DISLIKE_FETCH_TO_COMPLETE, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
LogHelper.printDebug(() -> "UI timed out waiting for dislike fetch to complete");
return;
} finally {
recordTimeUISpentWaitingForNetworkCall(fetchStartTime);
}
if (votingData == null) {
LogHelper.printDebug(() -> "Cannot add dislike count to UI (RYD data not available)");
Expand Down Expand Up @@ -293,4 +300,30 @@ private static String formatDislikePercentage(float dislikePercentage) {
// never will be reached, as the oldest supported YouTube app requires Android N or greater
return (int) (100 * dislikePercentage) + "%";
}


/**
* Number of times the UI was forced to wait on a network fetch to complete
*/
private static volatile int numberOfTimesUIWaitedOnNetworkCalls;

/**
* Total time the UI waited, of all times it was forced to wait.
*/
private static volatile long totalTimeUIWaitedOnNetworkCalls;

private static void recordTimeUISpentWaitingForNetworkCall(long timeUIWaitStarted) {
if (timeUIWaitStarted == 0 || !SettingsEnum.DEBUG.getBoolean()) {
return;
}
final long timeUIWaitingTotal = System.currentTimeMillis() - timeUIWaitStarted;
LogHelper.printDebug(() -> "UI thread waited for: " + timeUIWaitingTotal + "ms for vote fetch to complete");

totalTimeUIWaitedOnNetworkCalls += timeUIWaitingTotal;
numberOfTimesUIWaitedOnNetworkCalls++;
final long averageTimeForcedToWait = totalTimeUIWaitedOnNetworkCalls / numberOfTimesUIWaitedOnNetworkCalls;
LogHelper.printDebug(() -> "UI thread forced to wait: " + numberOfTimesUIWaitedOnNetworkCalls + " times, "
+ "total wait time: " + totalTimeUIWaitedOnNetworkCalls + "ms, "
+ "average wait time: " + averageTimeForcedToWait + "ms") ;
}
}
Loading

0 comments on commit 693ef08

Please sign in to comment.