Skip to content

Commit

Permalink
Stripe HTTP2 clients in CloudflareTurnCredentialsManager
Browse files Browse the repository at this point in the history
  • Loading branch information
ravi-signal committed Jan 8, 2025
1 parent 3a4a55c commit 3ca9a66
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 3 deletions.
1 change: 1 addition & 0 deletions service/config/sample.yml
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ turn:
- turns:%s:443?transport=tcp
ttl: 86400
hostname: turn.cloudflare.example.com
numHttpClients: 1

linkDevice:
secret: secret://linkDevice.secret
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,7 @@ public void run(WhisperServerConfiguration config, Environment environment) thro
config.getTurnConfiguration().cloudflare().urls(),
config.getTurnConfiguration().cloudflare().urlsWithIps(),
config.getTurnConfiguration().cloudflare().hostname(),
config.getTurnConfiguration().cloudflare().numHttpClients(),
config.getTurnConfiguration().cloudflare().circuitBreaker(),
cloudflareTurnHttpExecutor,
config.getTurnConfiguration().cloudflare().retry(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
package org.whispersystems.textsecuregcm.auth;

import com.fasterxml.jackson.core.JsonProcessingException;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Timer;
import io.netty.resolver.dns.DnsNameResolver;
import jakarta.ws.rs.core.Response;
import java.io.IOException;
Expand All @@ -22,13 +24,17 @@
import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration;
import org.whispersystems.textsecuregcm.configuration.RetryConfiguration;
import org.whispersystems.textsecuregcm.http.FaultTolerantHttpClient;
import org.whispersystems.textsecuregcm.metrics.MetricsUtil;
import org.whispersystems.textsecuregcm.util.ExceptionUtils;
import org.whispersystems.textsecuregcm.util.SystemMapper;

public class CloudflareTurnCredentialsManager {

private static final Logger logger = LoggerFactory.getLogger(CloudflareTurnCredentialsManager.class);

private static final String CREDENTIAL_FETCH_TIMER_NAME = MetricsUtil.name(CloudflareTurnCredentialsManager.class,
"credentialFetchLatency");

private final List<String> cloudflareTurnUrls;
private final List<String> cloudflareTurnUrlsWithIps;
private final String cloudflareTurnHostname;
Expand All @@ -51,15 +57,17 @@ record IceServer(
public CloudflareTurnCredentialsManager(final String cloudflareTurnApiToken,
final String cloudflareTurnEndpoint, final long cloudflareTurnTtl, final List<String> cloudflareTurnUrls,
final List<String> cloudflareTurnUrlsWithIps, final String cloudflareTurnHostname,
final CircuitBreakerConfiguration circuitBreaker, final ExecutorService executor, final RetryConfiguration retry,
final ScheduledExecutorService retryExecutor, final DnsNameResolver dnsNameResolver) {
final int cloudflareTurnNumHttpClients, final CircuitBreakerConfiguration circuitBreaker,
final ExecutorService executor, final RetryConfiguration retry, final ScheduledExecutorService retryExecutor,
final DnsNameResolver dnsNameResolver) {

this.cloudflareTurnClient = FaultTolerantHttpClient.newBuilder()
.withName("cloudflare-turn")
.withCircuitBreaker(circuitBreaker)
.withExecutor(executor)
.withRetry(retry)
.withRetryExecutor(retryExecutor)
.withNumClients(cloudflareTurnNumHttpClients)
.build();
this.cloudflareTurnUrls = cloudflareTurnUrls;
this.cloudflareTurnUrlsWithIps = cloudflareTurnUrlsWithIps;
Expand Down Expand Up @@ -93,11 +101,20 @@ public TurnToken retrieveFromCloudflare() throws IOException {
throw new IOException(e);
}

final Timer.Sample sample = Timer.start();
final HttpResponse<String> response;
try {
response = cloudflareTurnClient.sendAsync(request, HttpResponse.BodyHandlers.ofString()).join();
sample.stop(Timer.builder(CREDENTIAL_FETCH_TIMER_NAME)
.publishPercentileHistogram(true)
.tags("outcome", "success")
.register(Metrics.globalRegistry));
} catch (CompletionException e) {
logger.warn("failed to make http request to Cloudflare Turn: {}", e.getMessage());
sample.stop(Timer.builder(CREDENTIAL_FETCH_TIMER_NAME)
.publishPercentileHistogram(true)
.tags("outcome", "failure")
.register(Metrics.globalRegistry));
throw new IOException(ExceptionUtils.unwrap(e));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import jakarta.validation.constraints.Positive;
import org.whispersystems.textsecuregcm.configuration.secrets.SecretString;

public record CloudflareTurnConfiguration(@NotNull SecretString apiToken,
Expand All @@ -18,7 +19,8 @@ public record CloudflareTurnConfiguration(@NotNull SecretString apiToken,
@NotBlank List<String> urlsWithIps,
@NotNull @Valid CircuitBreakerConfiguration circuitBreaker,
@NotNull @Valid RetryConfiguration retry,
@NotBlank String hostname) {
@NotBlank String hostname,
@Positive int numHttpClients) {

public CloudflareTurnConfiguration {
if (circuitBreaker == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ void setUp() throws CertificateException {
List.of("turn:cf.example.com"),
List.of("turn:%s", "turn:%s:80?transport=tcp", "turns:%s:443?transport=tcp"),
TURN_HOSTNAME,
2,
new CircuitBreakerConfiguration(),
httpExecutor,
new RetryConfiguration(),
Expand Down
1 change: 1 addition & 0 deletions service/src/test/resources/config/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ turn:
- turn:%s:80?transport=tcp
- turns:%s:443?transport=tcp
hostname: turn.cloudflare.example.com
numHttpClients: 1

linkDevice:
secret: secret://linkDevice.secret
Expand Down

0 comments on commit 3ca9a66

Please sign in to comment.