-
Notifications
You must be signed in to change notification settings - Fork 450
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
Custom SslContext option added to ApnsClientBuilder #1086
Conversation
29f6e9f
to
4e833f0
Compare
Hello, and thank you for the contribution! I don't think I have a clear understanding of your use case. How many |
Hi. Thanks for quick reply! We normally use about 100 ApnsClient instances at the same time (there are 8 signing keys, but each one is used different applications with different topics, so about 100 combinations in total). The thing we want to do is a periodic verification that all our ApnsClients are configured properly (credentials are up to date, topics are allowed, etc). The reason is because the company is big and misconfiguration (in APNS admin console) happens. The way we go is to send dummy notifications with a short period (1 minute is short enough) to each combination of singing key and topic. If such misconfiguration happen, we want to know in advance (before main ApnsClient refreshed authentication of its connections), so we want this verification to be authenticated from scratch, without reusing of temporary tokens or any kind of session caching.
So we're going with approach to create multiple single-shot ApnsClient during each health check act to guarantee that every verification notification is sent with new authentication. And that activity (~100 checks per minute) takes about 0.35 CPU core in average continuously, which is almost the same as each our node consumes to send normal notifications. Profiling shows that 70-90% of time we spend in |
Thanks for the explanation! That does help me understand the problem a little better, but frankly, something's not adding up for me. You wrote:
It sounds like you think this time is dominated by constructed package com.eatthepath.pushy.apns;
import io.netty.handler.codec.http2.Http2SecurityUtil;
import io.netty.handler.ssl.*;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import javax.net.ssl.SSLException;
@State(Scope.Thread)
public class SslContextBenchmark {
@Benchmark
public SslContext buildSslContext() throws SSLException {
final SslContextBuilder sslContextBuilder = SslContextBuilder.forClient()
.sslProvider(SslProvider.OPENSSL)
.ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE);
return sslContextBuilder.build();
}
} …and on my humble laptop, I'm generating upwards of 50,000
That's four orders of magnitude off from what we'd expect from your numbers. I don't think On top of that, I think it's fair to say that your specific use case is uncommon, and reusing |
Well, more precisely, I'd say you're having a problem that's not common or easy to reproduce. From your flamegraph, it looks like Bouncycastle is spending an enormous amount of time… decrypting a trust store, it looks like? Perhaps there's a way to address that problem separately. It sounds like you have a good understanding of the problem, though:
But, yes:
…you're correct that this is my main point. It sounds like you have an uncommon use case (spawning lots of single-shot clients) combined with an uncommon problem (a higher-than-usual CPU load when loading trust stores). It's entirely possible that you're the only Pushy user who would benefit from the feature you're requesting, and it would come at a cost of complexity and some potential security risk to other users. For those reasons, I still think it makes sense to leave this change out of Pushy. I recognize that this may be disappointing for you, but I'm confident it's the right move for Pushy as a whole. I wish you luck in addressing the challenge by other means, though! |
Okay, thanks for considering my arguments and explanation of your point. |
I worried when I thought you unintentionally silenced me by closing PR... :) Regarding the problem - my only concern was to be sure that all arguments were considered. And they were and I completely respect your decision. Thanks for your time and attention! |
du to the facts mentioned above, SslContext initialisation takes considerable amount of CPU. The goal of this change is to reduce it by sharing SslContext between clients (we use signingKey to authenticate clients, so seems like it's correct to share SslContext).