From 4a0ef1f834c841af645472aa8badd23350409f5a Mon Sep 17 00:00:00 2001 From: Jon Chambers Date: Thu, 4 Aug 2022 10:33:19 -0400 Subject: [PATCH] Measure the time taken to send APNs push notifications --- .../textsecuregcm/push/APNSender.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/push/APNSender.java b/service/src/main/java/org/whispersystems/textsecuregcm/push/APNSender.java index 24813ffb7..70c994c52 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/push/APNSender.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/push/APNSender.java @@ -17,11 +17,16 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; +import java.time.Duration; import java.time.Instant; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; +import io.micrometer.core.instrument.Metrics; +import io.micrometer.core.instrument.Timer; import org.whispersystems.textsecuregcm.configuration.ApnConfiguration; +import static org.whispersystems.textsecuregcm.metrics.MetricsUtil.name; + public class APNSender implements Managed, PushNotificationSender { private final ExecutorService executor; @@ -45,6 +50,8 @@ public class APNSender implements Managed, PushNotificationSender { private static final String APNS_CA_FILENAME = "apns-certificates.pem"; + private static final Timer SEND_NOTIFICATION_TIMER = Metrics.timer(name(APNSender.class, "sendNotification")); + public APNSender(ExecutorService executor, ApnConfiguration configuration) throws IOException, NoSuchAlgorithmException, InvalidKeyException { @@ -95,6 +102,8 @@ public class APNSender implements Managed, PushNotificationSender { (notification.notificationType() == PushNotification.NotificationType.NOTIFICATION && !isVoip) ? "incoming-message" : null; + final Instant start = Instant.now(); + return apnsClient.sendNotification(new SimpleApnsPushNotification(notification.deviceToken(), topic, payload, @@ -102,6 +111,12 @@ public class APNSender implements Managed, PushNotificationSender { DeliveryPriority.IMMEDIATE, isVoip ? PushType.VOIP : PushType.ALERT, collapseId)) + .whenComplete((response, throwable) -> { + // Note that we deliberately run this small bit of non-blocking measurement on the "send notification" thread + // to avoid any measurement noise that could arise from dispatching to another executor and waiting in its + // queue + SEND_NOTIFICATION_TIMER.record(Duration.between(start, Instant.now())); + }) .thenApplyAsync(response -> { final boolean accepted; final String rejectionReason;