Skip to content

Commit

Permalink
优化网络连接体验
Browse files Browse the repository at this point in the history
  • Loading branch information
SuperIceCN committed May 7, 2023
1 parent f6445b4 commit 443e5e6
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 12 deletions.
5 changes: 3 additions & 2 deletions src/main/java/cn/powernukkitx/cli/cmd/JVMCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,13 @@ private static JsonArray getVMList() {
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://assets.powernukkitx.cn/jvms.json")).GET().build();
try {
var result = JsonParser.parseString(client.send(request, HttpResponse.BodyHandlers.ofString()).body());
var result = JsonParser.parseString(HttpUtils.joinFutureWithPlaceholder(
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())).body());
if (result.isJsonArray()) {
return result.getAsJsonArray();
}
return new JsonArray();
} catch (IOException | InterruptedException e) {
} catch (Exception e) {
return new JsonArray();
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/cn/powernukkitx/cli/cmd/PingCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public Integer call() throws Exception {
resultList.add(result);
}
}));
CompletableFuture.allOf(pingMap.values().toArray(CompletableFuture[]::new)).join();
HttpUtils.joinFutureWithPlaceholder(CompletableFuture.allOf(pingMap.values().toArray(CompletableFuture[]::new)));
if (resultList.isEmpty()) {
Logger.error(ansi().fgBrightRed().a(bundle.getString("no-available")));
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/cn/powernukkitx/cli/cmd/StartCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public Integer call() {
cmdBuilder.addXxOption(each);
}
if (generateOnly) {
Logger.raw(cmdBuilder.build());
Logger.raw(cmdBuilder.build() + "\n");
return 0;
}
cmdBuilder.addProperty("pnx.cli.path", OSUtils.getProgramPath());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,16 @@ private VersionListHelperV2() {
public static @NotNull ReleaseBean getLatestRelease() throws IOException, InterruptedException {
var client = HttpUtils.getClient();
var request = HttpRequest.newBuilder(URI.create(getAPIUrl() + "/git/latest-release/PowerNukkitX/PowerNukkitX")).GET().build();
var result = client.send(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)).body();
var future = client.sendAsync(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
var result = HttpUtils.joinFutureWithPlaceholder(future).body();
return ReleaseBean.from(JsonParser.parseString(result).getAsJsonObject());
}

public static @NotNull ReleaseBean @NotNull [] getAllReleases() throws IOException, InterruptedException {
var client = HttpUtils.getClient();
var request = HttpRequest.newBuilder(URI.create(getAPIUrl() + "/git/all-releases/PowerNukkitX/PowerNukkitX")).GET().build();
var result = client.send(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)).body();
var future = client.sendAsync(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
var result = HttpUtils.joinFutureWithPlaceholder(future).body();
var jsonArray = JsonParser.parseString(result).getAsJsonArray();
var releases = new ReleaseBean[jsonArray.size()];
for (int i = 0; i < releases.length; i++) {
Expand All @@ -44,14 +46,16 @@ private VersionListHelperV2() {
public static @NotNull BuildBean getLatestBuild() throws IOException, InterruptedException {
var client = HttpUtils.getClient();
var request = HttpRequest.newBuilder(URI.create(getAPIUrl() + "/git/latest-build/PowerNukkitX/PowerNukkitX")).GET().build();
var result = client.send(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)).body();
var future = client.sendAsync(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
var result = HttpUtils.joinFutureWithPlaceholder(future).body();
return BuildBean.from(JsonParser.parseString(result).getAsJsonObject());
}

public static @NotNull CompletableFuture<Map<String, RemoteFileBean>> getLatestReleaseLibs() {
var client = HttpUtils.getClient();
var request = HttpRequest.newBuilder(URI.create(getAPIUrl() + "/git/latest-release/PowerNukkitX/PowerNukkitX")).GET().build();
return client.sendAsync(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8))
return HttpUtils.warpFutureWithPlaceholder(
client.sendAsync(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)))
.thenApply(HttpResponse::body)
.thenApply(JsonParser::parseString)
.thenApply(jsonElement -> {
Expand All @@ -69,7 +73,8 @@ private VersionListHelperV2() {
public static @NotNull CompletableFuture<Map<String, RemoteFileBean>> getLatestBuildLibs() {
var client = HttpUtils.getClient();
var request = HttpRequest.newBuilder(URI.create(getAPIUrl() + "/git/latest-build/PowerNukkitX/PowerNukkitX")).GET().build();
return client.sendAsync(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8))
return HttpUtils.warpFutureWithPlaceholder(
client.sendAsync(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)))
.thenApply(HttpResponse::body)
.thenApply(JsonParser::parseString)
.thenApply(jsonElement -> BuildBean.from(jsonElement.getAsJsonObject()).libs())
Expand All @@ -82,11 +87,12 @@ private VersionListHelperV2() {
.uri(URI.create(getAPIUrl() + "/download/decompress/" + artifactBean.downloadId()))
.GET()
.build();
return client.sendAsync(decompressRequest, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8))
return HttpUtils.warpFutureWithPlaceholder(
client.sendAsync(decompressRequest, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)))
.thenApply(HttpResponse::body)
.thenApply(JsonParser::parseString)
.thenCompose(jsonElement ->
HttpUtils.getDelayedResponse(Main.getTimer(), RequestIDBean.from(jsonElement.getAsJsonObject())))
HttpUtils.warpFutureWithPlaceholder(HttpUtils.getDelayedResponse(Main.getTimer(), RequestIDBean.from(jsonElement.getAsJsonObject()))))
.thenApply(JsonParser::parseString)
.thenApply(jsonElement -> jsonElement.getAsJsonObject().entrySet())
.thenApply(entries -> {
Expand Down
81 changes: 81 additions & 0 deletions src/main/java/cn/powernukkitx/cli/util/HttpUtils.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cn.powernukkitx.cli.util;

import cn.powernukkitx.cli.Main;
import cn.powernukkitx.cli.data.bean.RequestIDBean;
import org.fusesource.jansi.Ansi;
import org.fusesource.jansi.AnsiConsole;
import org.jetbrains.annotations.NotNull;

Expand All @@ -14,6 +16,7 @@
import java.time.Duration;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

import static cn.powernukkitx.cli.util.ConfigUtils.debug;
Expand Down Expand Up @@ -94,6 +97,84 @@ public record EndpointAndPing(String endpoint, long ping) {
return pingList;
}

public static <T> T joinFutureWithPlaceholder(@NotNull CompletableFuture<T> connectionFuture) {
return joinFutureWithPlaceholder(Main.getTimer(), connectionFuture);
}

public static <T> T joinFutureWithPlaceholder(@NotNull Timer timer, @NotNull CompletableFuture<T> connectionFuture) {
if (connectionFuture.isDone()) {
return connectionFuture.join();
}
if (Ansi.isEnabled()) {
var atomicBoolean = new AtomicBoolean(false);
var timerTask = new TimerTask() {
public int time = 0;

@Override
public void run() {
if (connectionFuture.isDone()) {
this.cancel();
atomicBoolean.set(true);
Logger.clearProgress();
return;
}
time++;
Logger.raw(ansi().fgBrightYellow().a("[").a("/-\\|".charAt(time % 4))
.a("] ").a(".".repeat(time % 7)).reset().toString());
Logger.ProgressPrefixLength.addAndGet(4 + time % 7);
}
};
timer.schedule(timerTask, 10, 250);
var tmp = connectionFuture.join();
if (!atomicBoolean.get()) {
timerTask.cancel();
Logger.clearProgress();
}
return tmp;
}
return connectionFuture.join();
}

public static <T> @NotNull CompletableFuture<T> warpFutureWithPlaceholder(@NotNull CompletableFuture<T> connectionFuture) {
return warpFutureWithPlaceholder(Main.getTimer(), connectionFuture);
}

public static <T> @NotNull CompletableFuture<T> warpFutureWithPlaceholder(@NotNull Timer timer, @NotNull CompletableFuture<T> connectionFuture) {
if (connectionFuture.isDone()) {
return connectionFuture;
}
if (Ansi.isEnabled()) {
return CompletableFuture.supplyAsync(() -> {
var atomicBoolean = new AtomicBoolean(false);
var timerTask = new TimerTask() {
public int time = 0;

@Override
public void run() {
if (connectionFuture.isDone()) {
this.cancel();
atomicBoolean.set(true);
Logger.clearProgress();
return;
}
time++;
Logger.raw(ansi().fgBrightYellow().a("[").a("/-\\|".charAt(time % 4))
.a("] ").a(".".repeat(time % 7)).reset().toString());
Logger.ProgressPrefixLength.addAndGet(4 + time % 7);
}
};
timer.schedule(timerTask, 10, 250);
var tmp = connectionFuture.join();
if (!atomicBoolean.get()) {
timerTask.cancel();
Logger.clearProgress();
}
return tmp;
});
}
return connectionFuture;
}

public static @NotNull CompletableFuture<String> getDelayedResponse(@NotNull Timer timer, RequestIDBean requestIDBean) {
var completableFuture = new CompletableFuture<String>();
var timerTask = new TimerTask() {
Expand Down
23 changes: 22 additions & 1 deletion src/main/java/cn/powernukkitx/cli/util/Logger.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,68 @@

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.atomic.AtomicInteger;

import static org.fusesource.jansi.Ansi.ansi;

public final class Logger {
public static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");

public static final AtomicInteger ProgressPrefixLength = new AtomicInteger(0);

private Logger() {
throw new UnsupportedOperationException();
}

public static void clearProgress() {
var len = ProgressPrefixLength.get();
if (len != 0) {
System.out.print(ansi().eraseLine().cursorLeft(len));
len = ProgressPrefixLength.addAndGet(-len);
if (len != 0) {
clearProgress();
}
}
}

public static void info(String msg) {
clearProgress();
System.out.println(ansi().fgCyan().a(LocalDateTime.now().format(formatter))
.fgDefault().a(" [").fgBlue().a("INFO ").fgDefault().a("] ").fgDefault().a(msg).reset());
}

public static void info(Ansi msg) {
clearProgress();
System.out.println(ansi().fgCyan().a(LocalDateTime.now().format(formatter))
.fgDefault().a(" [").fgBlue().a("INFO ").fgDefault().a("] ").fgDefault().a(msg).reset());
}

public static void warn(String msg) {
clearProgress();
System.out.println(ansi().fgCyan().a(LocalDateTime.now().format(formatter))
.fgDefault().a(" [").fgRed().a("WARN ").fgDefault().a("] ").fgDefault().a(msg).reset());
}

public static void warn(Ansi msg) {
clearProgress();
System.out.println(ansi().fgCyan().a(LocalDateTime.now().format(formatter))
.fgDefault().a(" [").fgRed().a("WARN ").fgDefault().a("] ").fgDefault().a(msg).reset());
}

public static void error(String msg) {
clearProgress();
System.out.println(ansi().fgCyan().a(LocalDateTime.now().format(formatter))
.fgDefault().a(" [").fgBrightRed().a("ERROR").fgDefault().a("] ").fgDefault().a(msg).reset());
}

public static void error(Ansi msg) {
clearProgress();
System.out.println(ansi().fgCyan().a(LocalDateTime.now().format(formatter))
.fgDefault().a(" [").fgBrightRed().a("ERROR").fgDefault().a("] ").fgDefault().a(msg).reset());
}

public static void raw(String msg) {
System.out.println(msg);
clearProgress();
System.out.print(msg);
}
}

0 comments on commit 443e5e6

Please sign in to comment.