From 5355715e72fefb1b89178f6c100c5f6f4895dc16 Mon Sep 17 00:00:00 2001 From: Fedor Dudinsky Date: Fri, 26 Jul 2024 11:57:17 +0200 Subject: [PATCH 1/2] QQE-699 | Add a liveness probe to solve the problem of stuck GraphQL client --- pom.xml | 4 ++ .../activity/GitHubOpenPrQueueService.java | 6 ++- .../java/io/quarkus/activity/HangCheck.java | 41 +++++++++++++++++++ .../activity/graphql/GraphQLClient.java | 2 + src/main/resources/application.properties | 5 +++ 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/main/java/io/quarkus/activity/HangCheck.java diff --git a/pom.xml b/pom.xml index 1f505e6..535f4f3 100644 --- a/pom.xml +++ b/pom.xml @@ -71,6 +71,10 @@ io.quarkus quarkus-oidc + + io.quarkus + quarkus-smallrye-health + io.quarkus quarkus-junit5 diff --git a/src/main/java/io/quarkus/activity/GitHubOpenPrQueueService.java b/src/main/java/io/quarkus/activity/GitHubOpenPrQueueService.java index 69d2c63..1364d4a 100644 --- a/src/main/java/io/quarkus/activity/GitHubOpenPrQueueService.java +++ b/src/main/java/io/quarkus/activity/GitHubOpenPrQueueService.java @@ -1,8 +1,8 @@ package io.quarkus.activity; import java.io.IOException; -import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.Optional; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -46,4 +46,8 @@ public OpenPullRequestsQueueByRepositories getOpenPrQueueInOrganization() throws private OpenPullRequestsQueueByRepositories buildOpenPrQueueInOrganization() throws IOException { return gitHubService.getOpenPrQueueInOrganization(quarkusQeOrganization); } + + public synchronized Optional getLastUpdated() { + return Optional.ofNullable(openPrQueueInOrganization).map(queue -> queue.updated); + } } diff --git a/src/main/java/io/quarkus/activity/HangCheck.java b/src/main/java/io/quarkus/activity/HangCheck.java new file mode 100644 index 0000000..7156d20 --- /dev/null +++ b/src/main/java/io/quarkus/activity/HangCheck.java @@ -0,0 +1,41 @@ +package io.quarkus.activity; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import org.eclipse.microprofile.health.HealthCheck; +import org.eclipse.microprofile.health.HealthCheckResponse; +import org.eclipse.microprofile.health.HealthCheckResponseBuilder; +import org.eclipse.microprofile.health.Liveness; + +import java.time.LocalDateTime; + +@ApplicationScoped +@Liveness +/* + GraphQL client may stop to retrieve data properly (https://github.com/quarkusio/quarkus/issues/42029), + but restarting the app solves the problem. + + This class creates a liveness endpoint and checks, that PR queue was updated at least two hours ago. + If it wasn't (ie last 12 requests failed), the next liveness probe will fail and the pod restarted + */ +public class HangCheck implements HealthCheck { + + @Inject + GitHubOpenPrQueueService prService; + + @Override + public HealthCheckResponse call() { + HealthCheckResponseBuilder builder = HealthCheckResponse.named("GraphQL updates check"); + LocalDateTime twoHoursAgo = LocalDateTime.now().minusHours(2); + + builder.up(); + prService.getLastUpdated() + .filter(lastUpdated -> lastUpdated.isBefore(twoHoursAgo)) + .ifPresent(lastUpdated -> { + builder.down(); + builder.withData("lastUpdate", lastUpdated.toString()); + }); + + return builder.build(); + } +} diff --git a/src/main/java/io/quarkus/activity/graphql/GraphQLClient.java b/src/main/java/io/quarkus/activity/graphql/GraphQLClient.java index ffacab1..a1d59c8 100644 --- a/src/main/java/io/quarkus/activity/graphql/GraphQLClient.java +++ b/src/main/java/io/quarkus/activity/graphql/GraphQLClient.java @@ -1,6 +1,7 @@ package io.quarkus.activity.graphql; import io.vertx.core.json.JsonObject; +import jakarta.inject.Singleton; import org.eclipse.microprofile.faulttolerance.Retry; import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; @@ -12,6 +13,7 @@ @Retry(delay = 2, delayUnit = SECONDS) @RegisterRestClient(baseUri = "https://api.github.com/graphql") +@Singleton public interface GraphQLClient { @POST diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 53daf4d..09572e4 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -10,6 +10,11 @@ quarkus.http.auth.permission.roles.enabled=${activity.security.enabled} # restrict access to identities with 'quarkus-qe' role quarkus.http.auth.policy.roles-policy.roles-allowed=quarkus-qe +#Permit Kubernetest/OCP to access health endpoints without authorisation +quarkus.http.auth.permission.probes.paths=/q/health/* +quarkus.http.auth.permission.probes.policy=permit +quarkus.http.auth.permission.probes.methods=GET + quarkus.oidc.enabled=${activity.security.enabled} quarkus.oidc.application-type=web-app quarkus.oidc.auth-server-url=${oidc-server-url:} From e8632811ef120a2066024d2cf0571c95abc38927 Mon Sep 17 00:00:00 2001 From: Fedor Dudinsky Date: Fri, 26 Jul 2024 11:58:37 +0200 Subject: [PATCH 2/2] Add more colors for members of our team Monthly stats are shown with dedicated colors for the first 7 team members from `activity.logins` variable. Now there are 8 team members, so the last one in the list (fedinskiy) receives a different random color for every graph on the same page. This commit adds two additional colors, one for fedinskiy and another for a potential future team member. --- src/main/resources/templates/monthlyStats.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/resources/templates/monthlyStats.html b/src/main/resources/templates/monthlyStats.html index 0f6c913..3e971ed 100644 --- a/src/main/resources/templates/monthlyStats.html +++ b/src/main/resources/templates/monthlyStats.html @@ -252,6 +252,7 @@

Issues created per month in QuarkusIO GitHub organisation

} } function getColor(index) { + // there are currently 8 of us, +1 for a backup if (index == 0) { return 'rgba(255, 99, 132, 0.8)'} if (index == 1) { return 'rgba(255, 159, 64, 0.8)'} if (index == 2) { return 'rgba(255, 205, 86, 0.8)'} @@ -259,6 +260,8 @@

Issues created per month in QuarkusIO GitHub organisation

if (index == 4) { return 'rgba(54, 162, 245, 0.8)'} if (index == 5) { return 'rgba(153, 102, 255, 0.8)'} if (index == 6) { return 'rgba(191, 201, 202, 0.8)'} + if (index == 7) { return 'rgba(29, 191, 58, 0.8)'} + if (index == 8) { return 'rgba(1, 1, 1, 0.8)'} var letters = '0123456789ABCDEF'.split(''); var color = '#'; for (var i = 0; i < 6; i++ ) {