Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Utilize Class Data Sharing to improve startup time #868

Draft
wants to merge 2 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
GRADLE_CLI_OPTS: ""
run: "chmod +x ./gradlew && ./gradlew ${GRADLE_CLI_OPTS} -Pversion=${API_VERSION} build jacocoTestReport"
- name: Build and push Docker images
if: github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/tags')
if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/cds' || startsWith(github.ref, 'refs/tags')
uses: docker/[email protected]
with:
username: ${{ secrets.DOCKER_USERNAME }}
Expand Down
20 changes: 13 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@ FROM eclipse-temurin:21-jdk-alpine as builder
WORKDIR /application
ARG JAR_FILE=build/libs/faf-java-api-*.jar
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract
COPY test-pki-private.key /pki/secret.key
COPY test-pki-public.key /pki/public.key
COPY test-account-activation.html /config/mail/account-activation.html
COPY test-password-reset.html /config/mail/password-reset.html
COPY test-welcome-to-faf.html /config/mail/welcome-to-faf.html
ENV FAF_DOMAIN=faforever.com
ENV CHALLONGE_KEY=test
RUN java -Djarmode=tools -jar application.jar extract
RUN java -Dspring.context.exit=onRefresh -Dspring.profiles.active=training -XX:ArchiveClassesAtExit=application.jsa -jar application/application.jar

FROM eclipse-temurin:21-jdk-alpine
VOLUME /tmp
WORKDIR /application
COPY --from=builder /application/dependencies/ ./
COPY --from=builder /application/application/lib ./application/lib
RUN true
COPY --from=builder /application/spring-boot-loader/ ./
COPY --from=builder /application/application/application.jar ./application
RUN true
COPY --from=builder /application/snapshot-dependencies/ ./
COPY --from=builder /application/application.jsa ./
RUN true
COPY --from=builder /application/application/ ./
RUN true
ENTRYPOINT ["java", "-server", "-Djava.security.egd=file:/dev/./urandom", "org.springframework.boot.loader.launch.JarLauncher"]
ENTRYPOINT ["java", "-XX:SharedArchiveFile=application.jsa", "-Djava.security.egd=file:/dev/./urandom", "-jar", "application/application.jar"]
16 changes: 10 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ buildscript {

plugins {
id "java"
id "org.springframework.boot" version "3.3.0"
id "org.springframework.boot" version "3.3.1"
id "idea"
id "com.adarshr.test-logger" version "4.0.0"
}
Expand All @@ -31,15 +31,18 @@ repositories {
maven { url "https://jitpack.io" }
}

compileJava.dependsOn(processResources)
compileJava {
dependsOn(processResources)
options.compilerArgs.add("-parameters")
}

configurations {
compile.exclude module: "assertj-core"
}

idea {
module {
testSourceDirs += file('src/inttest/java')
testSources = files(file("src/test/java"), file("src/inttest/java"))
}
}

Expand All @@ -66,7 +69,7 @@ configurations {
}


task inttest(type: Test) {
tasks.register('inttest', Test) {
group = LifecycleBasePlugin.VERIFICATION_GROUP
description = "Runs the integration tests."

Expand Down Expand Up @@ -105,13 +108,14 @@ configurations {
codacy
}

task sendCoverageToCodacy(type: JavaExec, dependsOn: jacocoTestReport) {
tasks.register('sendCoverageToCodacy', JavaExec) {
dependsOn jacocoTestReport
mainClass = "com.codacy.CodacyCoverageReporter"
classpath = configurations.codacy
args = ["report", "-l", "Java", "-r", "${buildDir}/reports/jacoco/test/jacocoTestReport.xml"]
}

configurations.all {
configurations.configureEach {
// Cache -SNAPSHOT for 60 seconds only
resolutionStrategy.cacheChangingModulesFor 60, 'seconds'
}
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@

import com.faforever.api.config.FafApiProperties;
import com.faforever.api.config.FafApiProperties.Challonge;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
Expand All @@ -22,7 +21,6 @@
import org.springframework.web.util.DefaultUriBuilderFactory;
import org.springframework.web.util.UriBuilder;

import jakarta.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

Expand All @@ -37,7 +35,6 @@
* only loaded if a Challonge API key is specified.</p>
*/
@RestController
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
@RequestMapping(path = ChallongeController.CHALLONGE_ROUTE)
@ConditionalOnProperty("faf-api.challonge.key")
public class ChallongeController {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public final class ApplicationProfile {
public static final String PRODUCTION = "prod";
public static final String DEVELOPMENT = "dev";
public static final String INTEGRATION_TEST = "int";
public static final String TRAINING = "training";

private ApplicationProfile() {
// Utility class
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/faforever/api/config/CacheConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.faforever.api.data.domain.MapVersion;
import com.faforever.api.data.domain.Mod;
import com.faforever.api.data.domain.ModVersion;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCache;
Expand All @@ -28,7 +29,6 @@
import org.springframework.context.annotation.Profile;
import org.springframework.web.servlet.HandlerMapping;

import jakarta.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
Expand All @@ -40,7 +40,7 @@

@EnableCaching(proxyTargetClass = true)
@Configuration
@Profile(ApplicationProfile.PRODUCTION)
@Profile({ApplicationProfile.PRODUCTION, ApplicationProfile.TRAINING})
public class CacheConfig {

/**
Expand Down
11 changes: 1 addition & 10 deletions src/main/java/com/faforever/api/config/LocalizationConfig.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
package com.faforever.api.config;

import com.faforever.api.i18n.RepositoryMessageSource;
import org.springframework.context.HierarchicalMessageSource;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.MessageSourceAccessor;

import jakarta.inject.Inject;

@Configuration
public class LocalizationConfig {

@Bean
public MessageSourceAccessor messageSourceAccessor(MessageSource messageSource) {
public MessageSourceAccessor messageSourceAccessor(RepositoryMessageSource messageSource) {
return new MessageSourceAccessor(messageSource);
}

@Inject
public void configureMessageSource(HierarchicalMessageSource messageSource, RepositoryMessageSource repositoryMessageSource) {
messageSource.setParentMessageSource(repositoryMessageSource);
}
}
5 changes: 3 additions & 2 deletions src/main/java/com/faforever/api/config/elide/ElideConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.yahoo.elide.jsonapi.JsonApiSettings;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -35,8 +36,8 @@ public class ElideConfig {

@Bean
MultiplexManager multiplexDataStore(
DataStore fafDataStore,
DataStore leagueDataStore
@Qualifier("fafDataStore") DataStore fafDataStore,
@Qualifier("leagueDataStore")DataStore leagueDataStore
) {
return new MultiplexManager(fafDataStore, leagueDataStore);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import java.util.Objects;

@Component
@Profile("!" + ApplicationProfile.INTEGRATION_TEST)
@Profile(ApplicationProfile.PRODUCTION)
public class SchemaVersionVerifier implements PriorityOrdered, InitializingBean {

private final SchemaVersionRepository schemaVersionRepository;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package com.faforever.api.i18n;

import com.faforever.api.config.ApplicationProfile;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.support.AbstractResourceBasedMessageSource;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

@Component
@RequiredArgsConstructor
Expand All @@ -18,6 +21,7 @@ public class RepositoryMessageSource extends AbstractResourceBasedMessageSource
private static final Locale FALLBACK_LOCALE = Locale.US;

private final MessageRepository messageRepository;
private final Environment environment;

/**
* Language -&gt; Region -&gt; Key -&gt; Value.
Expand Down Expand Up @@ -76,6 +80,6 @@ private String getText(String key, Locale locale) {

@Override
public void afterPropertiesSet() {
messagesByLanguage = loadMessages();
messagesByLanguage = Set.of(environment.getActiveProfiles()).contains(ApplicationProfile.TRAINING) ? Map.of() : loadMessages();
}
}
8 changes: 4 additions & 4 deletions src/main/resources/config/application-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ spring:
rabbitmq:
host: ${RABBIT_HOST:127.0.0.1}
port: ${RABBIT_PORT:5672}
username: ${RABBIT_USERNAME:faf-java-api}
username: ${RABBIT_USERNAME:faf-api}
password: ${RABBIT_PASSWORD:banana}
virtual-host: ${RABBIT_VHOST:/faf-core}
jpa:
Expand All @@ -80,8 +80,8 @@ spring:
oauth2:
resourceserver:
jwt:
jwk-set-uri: https://hydra.faforever.com/.well-known/jwks.json
issuer-uri: https://hydra.faforever.com/
jwk-set-uri: http://localhost:4444/.well-known/jwks.json
issuer-uri: http://ory-hydra:4444/
logging:
level:
com.faforever.api: debug
com.faforever.api: debug
2 changes: 2 additions & 0 deletions src/main/resources/config/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ spring:
resourceserver:
jwt:
issuer-uri: ${JWT_FAF_HYDRA_ISSUER:https://hydra.${FAF_DOMAIN}/}
aot:
enabled: true

server:
# Mind that this is configured in the docker compose file as well (that is, in the gradle script that generates it)
Expand Down
Loading