Kotlinify some more things

This commit is contained in:
carbotaniuman 2020-06-13 18:19:04 -05:00
parent 57ba8eb019
commit 9afa914566
13 changed files with 61 additions and 139 deletions

View file

@ -4,6 +4,7 @@ plugins {
id "application" id "application"
id "com.github.johnrengelman.shadow" version "5.2.0" id "com.github.johnrengelman.shadow" version "5.2.0"
id "com.diffplug.gradle.spotless" version "3.18.0" id "com.diffplug.gradle.spotless" version "3.18.0"
id 'dev.afanasev.sekret' version '0.0.3'
} }
group = "com.mangadex" group = "com.mangadex"
@ -26,8 +27,10 @@ dependencies {
implementation group: "commons-io", name: "commons-io", version: "2.7" implementation group: "commons-io", name: "commons-io", version: "2.7"
implementation "ch.qos.logback:logback-classic:$logback_version" implementation group:"ch.qos.logback", name: "logback-classic", version: "$logback_version"
runtimeOnly 'io.netty:netty-tcnative-boringssl-static:2.0.30.Final' runtimeOnly group:"io.netty", name: "netty-tcnative-boringssl-static", version: "2.0.30.Final"
compileOnly group:"dev.afanasev", name: "sekret-annotation", version: "0.0.3"
} }
java { java {

View file

@ -1,9 +0,0 @@
package mdnet.base;
import java.time.Duration;
public class Constants {
public static final int CLIENT_BUILD = 5;
public static final String CLIENT_VERSION = "1.0";
public static final Duration MAX_AGE_CACHE = Duration.ofDays(14);
}

View file

@ -3,8 +3,8 @@ package mdnet.base;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import mdnet.base.settings.ClientSettings; import mdnet.base.settings.ClientSettings;
import mdnet.base.web.ApplicationKt; import mdnet.base.server.ApplicationKt;
import mdnet.base.web.WebUiKt; import mdnet.base.server.WebUiKt;
import mdnet.cache.DiskLruCache; import mdnet.cache.DiskLruCache;
import org.http4k.server.Http4kServer; import org.http4k.server.Http4kServer;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -32,10 +32,10 @@ public class MangaDexClient {
private final ClientSettings clientSettings; private final ClientSettings clientSettings;
private final Map<Instant, Statistics> statsMap = Collections private final Map<Instant, Statistics> statsMap = Collections
.synchronizedMap(new LinkedHashMap<Instant, Statistics>(80) { .synchronizedMap(new LinkedHashMap<Instant, Statistics>(240) {
@Override @Override
protected boolean removeEldestEntry(Map.Entry eldest) { protected boolean removeEldestEntry(Map.Entry eldest) {
return this.size() > 80; return this.size() > 240;
} }
}); });
private final AtomicReference<Statistics> statistics; private final AtomicReference<Statistics> statistics;
@ -66,7 +66,6 @@ public class MangaDexClient {
} else { } else {
statistics.set(new Statistics()); statistics.set(new Statistics());
} }
lastBytesSent = statistics.get().getBytesSent();
} catch (IOException e) { } catch (IOException e) {
MangaDexClient.dieWithError(e); MangaDexClient.dieWithError(e);
} }
@ -81,6 +80,7 @@ public class MangaDexClient {
} }
} }
lastBytesSent = statistics.get().getBytesSent();
statsMap.put(Instant.now(), statistics.get()); statsMap.put(Instant.now(), statistics.get());
if (clientSettings.getWebSettings() != null) { if (clientSettings.getWebSettings() != null) {
@ -89,9 +89,29 @@ public class MangaDexClient {
} }
if (LOGGER.isInfoEnabled()) { if (LOGGER.isInfoEnabled()) {
LOGGER.info("MDNet initialization completed successfully. Starting normal operation."); LOGGER.info("Mangadex@Home Client initialization completed successfully. Starting normal operation.");
} }
executorService.scheduleWithFixedDelay(() -> {
statistics.updateAndGet(n -> n.copy(n.getRequestsServed(), n.getCacheHits(), n.getCacheMisses(),
n.getBrowserCached(), n.getBytesSent(), cache.size()));
statsMap.put(Instant.now(), statistics.get());
try {
DiskLruCache.Editor editor = cache.edit("statistics");
if (editor != null) {
String json = GSON.toJson(statistics.get(), Statistics.class);
editor.setString(0, json);
editor.setString(1, "");
editor.setString(2, "");
editor.commit();
}
} catch (IOException ignored) {
}
}, 15, 15, TimeUnit.SECONDS);
executorService.scheduleAtFixedRate(() -> { executorService.scheduleAtFixedRate(() -> {
if (counter == 80) { if (counter == 80) {
counter = 0; counter = 0;
@ -108,20 +128,6 @@ public class MangaDexClient {
counter++; counter++;
} }
statsMap.put(Instant.now(), statistics.get());
try {
DiskLruCache.Editor editor = cache.edit("statistics");
if (editor != null) {
String json = GSON.toJson(statistics.get(), Statistics.class);
editor.setString(0, json);
editor.setString(1, "");
editor.setString(2, "");
editor.commit();
}
} catch (IOException ignored) {
}
// if the server is offline then don't try and refresh certs // if the server is offline then don't try and refresh certs
if (engine == null) { if (engine == null) {
return; return;

View file

@ -1,77 +0,0 @@
package mdnet.base.settings;
import com.google.gson.annotations.SerializedName;
import java.util.Objects;
public final class ClientSettings {
@SerializedName("max_cache_size_mib")
private final long maxCacheSizeMib;
@SerializedName("max_bandwidth_mib_per_hour")
private final long maxBandwidthMibPerHour;
@SerializedName("max_burst_rate_kib_per_second")
private final long maxBurstRateKibPerSecond;
@SerializedName("client_port")
private final int clientPort;
@SerializedName("client_secret")
private final String clientSecret;
@SerializedName("threads")
private final int threads;
@SerializedName("web_settings")
private final WebSettings webSettings;
public ClientSettings() {
this.maxCacheSizeMib = 20480;
this.maxBandwidthMibPerHour = 0;
this.maxBurstRateKibPerSecond = 0;
this.clientPort = 443;
this.clientSecret = "PASTE-YOUR-SECRET-HERE";
this.threads = 32;
this.webSettings = null;
}
public ClientSettings(long maxCacheSizeMib, long maxBandwidthMibPerHour, long maxBurstRateKibPerSecond,
int clientPort, String clientSecret, int threads, WebSettings webSettings) {
this.maxCacheSizeMib = maxCacheSizeMib;
this.maxBandwidthMibPerHour = maxBandwidthMibPerHour;
this.maxBurstRateKibPerSecond = maxBurstRateKibPerSecond;
this.clientPort = clientPort;
this.clientSecret = Objects.requireNonNull(clientSecret);
this.threads = threads;
this.webSettings = webSettings;
}
public long getMaxCacheSizeMib() {
return maxCacheSizeMib;
}
public long getMaxBandwidthMibPerHour() {
return maxBandwidthMibPerHour;
}
public long getMaxBurstRateKibPerSecond() {
return maxBurstRateKibPerSecond;
}
public int getClientPort() {
return clientPort;
}
public String getClientSecret() {
return clientSecret;
}
public WebSettings getWebSettings() {
return webSettings;
}
public int getThreads() {
return threads;
}
@Override
public String toString() {
return "ClientSettings{" + "maxCacheSizeMib=" + maxCacheSizeMib + ", maxBandwidthMibPerHour="
+ maxBandwidthMibPerHour + ", maxBurstRateKibPerSecond=" + maxBurstRateKibPerSecond + ", clientPort="
+ clientPort + ", clientSecret='" + "<hidden>" + '\'' + ", threads=" + getThreads() + '}';
}
}

View file

@ -1,25 +0,0 @@
package mdnet.base.settings;
import com.google.gson.annotations.SerializedName;
public final class WebSettings {
@SerializedName("ui_port")
private final int uiPort;
public WebSettings() {
this.uiPort = 8080;
}
public WebSettings(int uiPort) {
this.uiPort = uiPort;
}
public int getUiPort() {
return uiPort;
}
@Override
public String toString() {
return "WebSettings{" + "uiPort=" + uiPort + '}';
}
}

View file

@ -0,0 +1,9 @@
package mdnet.base
import java.time.Duration
object Constants {
const val CLIENT_BUILD = 5
const val CLIENT_VERSION = "1.0"
val MAX_AGE_CACHE: Duration = Duration.ofDays(14)
}

View file

@ -45,7 +45,7 @@ class Netty(private val tls: ServerSettings.TlsCert, private val clientSettings:
private lateinit var address: InetSocketAddress private lateinit var address: InetSocketAddress
private val burstLimiter = object : GlobalTrafficShapingHandler( private val burstLimiter = object : GlobalTrafficShapingHandler(
workerGroup, 1024 * clientSettings.maxBurstRateKibPerSecond, 0, 50) { workerGroup, 1024L * clientSettings.maxBurstRateKibPerSecond, 0, 50) {
override fun doAccounting(counter: TrafficCounter) { override fun doAccounting(counter: TrafficCounter) {
statistics.getAndUpdate { statistics.getAndUpdate {
it.copy(bytesSent = it.bytesSent + counter.cumulativeWrittenBytes()) it.copy(bytesSent = it.bytesSent + counter.cumulativeWrittenBytes())

View file

@ -1,5 +1,5 @@
/* ktlint-disable no-wildcard-imports */ /* ktlint-disable no-wildcard-imports */
package mdnet.base.web package mdnet.base.server
import mdnet.base.Netty import mdnet.base.Netty
import mdnet.base.ServerSettings import mdnet.base.ServerSettings

View file

@ -1,5 +1,5 @@
/* ktlint-disable no-wildcard-imports */ /* ktlint-disable no-wildcard-imports */
package mdnet.base.web package mdnet.base.server
import mdnet.base.Constants import mdnet.base.Constants
import mdnet.base.Statistics import mdnet.base.Statistics

View file

@ -1,5 +1,5 @@
/* ktlint-disable no-wildcard-imports */ /* ktlint-disable no-wildcard-imports */
package mdnet.base.web package mdnet.base.server
import mdnet.base.Statistics import mdnet.base.Statistics
import mdnet.base.settings.WebSettings import mdnet.base.settings.WebSettings

View file

@ -1,5 +1,5 @@
/* ktlint-disable no-wildcard-imports */ /* ktlint-disable no-wildcard-imports */
package mdnet.base.web package mdnet.base.server
import mdnet.base.Constants import mdnet.base.Constants
import org.http4k.core.Filter import org.http4k.core.Filter

View file

@ -0,0 +1,16 @@
package mdnet.base.settings
import com.google.gson.annotations.SerializedName
import dev.afanasev.sekret.Secret
data class ClientSettings(
@field:SerializedName("max_cache_size_mib") val maxCacheSizeMib: Long = 20480,
@field:SerializedName("max_bandwidth_mib_per_hour") val maxBandwidthMibPerHour: Long = 0,
@field:SerializedName("max_burst_rate_kib_per_second") val maxBurstRateKibPerSecond: Long = 0,
@field:SerializedName("client_port") val clientPort: Int = 443,
@field:Secret @field:SerializedName("client_secret") val clientSecret: String = "PASTE-YOUR-SECRET-HERE",
@field:SerializedName("threads") val threads: Int = 32,
@field:SerializedName("web_settings") val webSettings: WebSettings? = null
)
data class WebSettings(@field:SerializedName("ui_port") val uiPort: Int = 8080)

View file

@ -1,5 +1,4 @@
<configuration> <configuration>
<shutdownHook/>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>${file-level:-TRACE}</level> <level>${file-level:-TRACE}</level>