-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.java
77 lines (66 loc) · 2.66 KB
/
main.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.*;
import java.util.function.BiConsumer;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
class Main {
private static final String UserAgent = System.getenv().getOrDefault("USER_AGENT", "java-http-client");
private static final Integer CONCURRENCY = getEnv("CONCURRENCY", 10);
private static final Integer RequestTimeout = getEnv("REQUEST_TIMEOUT", 5);
private static final Semaphore semaphore = new Semaphore(CONCURRENCY);
private static final HttpClient CLIENT = HttpClient.newBuilder()
.followRedirects(HttpClient.Redirect.ALWAYS)
.version(HttpClient.Version.HTTP_1_1)
.build();
private static HttpRequest buildHttpRequest(String url) {
return HttpRequest.newBuilder()
.uri(URI.create(url))
.header("User-Agent", UserAgent)
.GET()
.build();
}
private static Integer getEnv(String variableName, Integer defaultValue) {
String value = System.getenv(variableName);
return value != null ? Integer.parseInt(value) : defaultValue;
}
public static CompletableFuture<Void> makeRequest(String url) {
var startTime = Instant.now();
BiConsumer<String, Integer> onComplete = (code, bodyLength) -> {
var duration = Duration.between(startTime, Instant.now()).toMillis();
System.out.println(url + "," + code + "," + startTime + "," + duration + "," + bodyLength);
};
try {
semaphore.acquire();
} catch (InterruptedException e) {
onComplete.accept("InterruptedException", 0);
return CompletableFuture.completedFuture(null);
}
return CLIENT.sendAsync(buildHttpRequest(url), HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8))
.orTimeout(RequestTimeout, TimeUnit.SECONDS)
.thenAccept(response -> {
var bodyLength = response.body().length();
var code = Integer.toString(response.statusCode());
onComplete.accept(code, bodyLength);
})
.exceptionally(ex -> {
var cause = ex.getCause();
var code = (cause != null ? cause : ex).getClass().getSimpleName();
onComplete.accept(code, 0);
return null;
})
.whenComplete((_, _) -> semaphore.release());
}
public static void main(String[] args) {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
var futures = reader.lines()
.map(Main::makeRequest)
.toList();
CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new)).join();
}
}