DownloadQueue.java
net.minecraft.server.packs.DownloadQueue
信息
- 全限定名:net.minecraft.server.packs.DownloadQueue
- 类型:public class
- 包:net.minecraft.server.packs
- 源码路径:src/main/java/net/minecraft/server/packs/DownloadQueue.java
- 起始行号:L32
- 实现:AutoCloseable
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L33 - 说明:
TODO
- 类型:
-
MAX_KEPT_PACKS- 类型:
int - 修饰符:
private static final - 源码定位:
L34 - 说明:
TODO
- 类型:
-
cacheDir- 类型:
Path - 修饰符:
private final - 源码定位:
L35 - 说明:
TODO
- 类型:
-
eventLog- 类型:
JsonEventLog<DownloadQueue.LogEntry> - 修饰符:
private final - 源码定位:
L36 - 说明:
TODO
- 类型:
-
tasks- 类型:
ConsecutiveExecutor - 修饰符:
private final - 源码定位:
L37 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.server.packs.DownloadQueue.BatchConfig- 类型:
record - 修饰符:
public - 源码定位:
L103 - 说明:
TODO
- 类型:
-
net.minecraft.server.packs.DownloadQueue.BatchResult- 类型:
record - 修饰符:
public - 源码定位:
L106 - 说明:
TODO
- 类型:
-
net.minecraft.server.packs.DownloadQueue.DownloadRequest- 类型:
record - 修饰符:
public - 源码定位:
L112 - 说明:
TODO
- 类型:
-
net.minecraft.server.packs.DownloadQueue.FileInfoEntry- 类型:
record - 修饰符:
private - 源码定位:
L115 - 说明:
TODO
- 类型:
-
net.minecraft.server.packs.DownloadQueue.LogEntry- 类型:
record - 修饰符:
private - 源码定位:
L125 - 说明:
TODO
- 类型:
构造器
public DownloadQueue(Path cacheDir) @ L39
- 构造器名:DownloadQueue
- 源码定位:L39
- 修饰符:public
参数:
- cacheDir: Path
说明:
TODO
方法
下面的方法块按源码顺序生成。
private DownloadQueue.BatchResult runDownload(DownloadQueue.BatchConfig config, Map<UUID,DownloadQueue.DownloadRequest> requests) @ L46
- 方法名:runDownload
- 源码定位:L46
- 返回类型:DownloadQueue.BatchResult
- 修饰符:private
参数:
- config: DownloadQueue.BatchConfig
- requests: Map<UUID,DownloadQueue.DownloadRequest>
说明:
TODO
private Either<String,DownloadQueue.FileInfoEntry> getFileInfo(Path downloadedFile) @ L82
- 方法名:getFileInfo
- 源码定位:L82
- 返回类型:Either<String,DownloadQueue.FileInfoEntry>
- 修饰符:private
参数:
- downloadedFile: Path
说明:
TODO
public CompletableFuture<DownloadQueue.BatchResult> downloadBatch(DownloadQueue.BatchConfig config, Map<UUID,DownloadQueue.DownloadRequest> requests) @ L93
- 方法名:downloadBatch
- 源码定位:L93
- 返回类型:CompletableFuture<DownloadQueue.BatchResult>
- 修饰符:public
参数:
- config: DownloadQueue.BatchConfig
- requests: Map<UUID,DownloadQueue.DownloadRequest>
说明:
TODO
public void close() @ L97
- 方法名:close
- 源码定位:L97
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
代码
public class DownloadQueue implements AutoCloseable {
private static final Logger LOGGER = LogUtils.getLogger();
private static final int MAX_KEPT_PACKS = 20;
private final Path cacheDir;
private final JsonEventLog<DownloadQueue.LogEntry> eventLog;
private final ConsecutiveExecutor tasks = new ConsecutiveExecutor(Util.nonCriticalIoPool(), "download-queue");
public DownloadQueue(Path cacheDir) throws IOException {
this.cacheDir = cacheDir;
FileUtil.createDirectoriesSafe(cacheDir);
this.eventLog = JsonEventLog.open(DownloadQueue.LogEntry.CODEC, cacheDir.resolve("log.json"));
DownloadCacheCleaner.vacuumCacheDir(cacheDir, 20);
}
private DownloadQueue.BatchResult runDownload(DownloadQueue.BatchConfig config, Map<UUID, DownloadQueue.DownloadRequest> requests) {
DownloadQueue.BatchResult result = new DownloadQueue.BatchResult();
requests.forEach(
(id, request) -> {
Path targetDir = this.cacheDir.resolve(id.toString());
Path downloadedFile = null;
try {
downloadedFile = HttpUtil.downloadFile(
targetDir, request.url, config.headers, config.hashFunction, request.hash, config.maxSize, config.proxy, config.listener
);
result.downloaded.put(id, downloadedFile);
} catch (Exception var9) {
LOGGER.error("Failed to download {}", request.url, var9);
result.failed.add(id);
}
try {
this.eventLog
.write(
new DownloadQueue.LogEntry(
id,
request.url.toString(),
Instant.now(),
Optional.ofNullable(request.hash).map(HashCode::toString),
downloadedFile != null ? this.getFileInfo(downloadedFile) : Either.left("download_failed")
)
);
} catch (Exception var8) {
LOGGER.error("Failed to log download of {}", request.url, var8);
}
}
);
return result;
}
private Either<String, DownloadQueue.FileInfoEntry> getFileInfo(Path downloadedFile) {
try {
long size = Files.size(downloadedFile);
Path relativePath = this.cacheDir.relativize(downloadedFile);
return Either.right(new DownloadQueue.FileInfoEntry(relativePath.toString(), size));
} catch (IOException var5) {
LOGGER.error("Failed to get file size of {}", downloadedFile, var5);
return Either.left("no_access");
}
}
public CompletableFuture<DownloadQueue.BatchResult> downloadBatch(DownloadQueue.BatchConfig config, Map<UUID, DownloadQueue.DownloadRequest> requests) {
return CompletableFuture.supplyAsync(() -> this.runDownload(config, requests), this.tasks::schedule);
}
@Override
public void close() throws IOException {
this.tasks.close();
this.eventLog.close();
}
public record BatchConfig(HashFunction hashFunction, int maxSize, Map<String, String> headers, Proxy proxy, HttpUtil.DownloadProgressListener listener) {
}
public record BatchResult(Map<UUID, Path> downloaded, Set<UUID> failed) {
public BatchResult() {
this(new HashMap<>(), new HashSet<>());
}
}
public record DownloadRequest(URL url, @Nullable HashCode hash) {
}
private record FileInfoEntry(String name, long size) {
public static final Codec<DownloadQueue.FileInfoEntry> CODEC = RecordCodecBuilder.create(
i -> i.group(
Codec.STRING.fieldOf("name").forGetter(DownloadQueue.FileInfoEntry::name),
Codec.LONG.fieldOf("size").forGetter(DownloadQueue.FileInfoEntry::size)
)
.apply(i, DownloadQueue.FileInfoEntry::new)
);
}
private record LogEntry(UUID id, String url, Instant time, Optional<String> hash, Either<String, DownloadQueue.FileInfoEntry> errorOrFileInfo) {
public static final Codec<DownloadQueue.LogEntry> CODEC = RecordCodecBuilder.create(
i -> i.group(
UUIDUtil.STRING_CODEC.fieldOf("id").forGetter(DownloadQueue.LogEntry::id),
Codec.STRING.fieldOf("url").forGetter(DownloadQueue.LogEntry::url),
ExtraCodecs.INSTANT_ISO8601.fieldOf("time").forGetter(DownloadQueue.LogEntry::time),
Codec.STRING.optionalFieldOf("hash").forGetter(DownloadQueue.LogEntry::hash),
Codec.mapEither(Codec.STRING.fieldOf("error"), DownloadQueue.FileInfoEntry.CODEC.fieldOf("file"))
.forGetter(DownloadQueue.LogEntry::errorOrFileInfo)
)
.apply(i, DownloadQueue.LogEntry::new)
);
}
}引用的其他类
-
- 引用位置:
方法调用 - 关联成员:
DownloadCacheCleaner.vacuumCacheDir()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
FileUtil.createDirectoriesSafe()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
HttpUtil.downloadFile()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.nonCriticalIoPool()
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
JsonEventLog.open()
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
ConsecutiveExecutor()
- 引用位置: