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

LDStreamingMode.streaming incompatible with some Proxy servers #406

Open
swhitty opened this issue Aug 8, 2024 · 6 comments
Open

LDStreamingMode.streaming incompatible with some Proxy servers #406

swhitty opened this issue Aug 8, 2024 · 6 comments

Comments

@swhitty
Copy link

swhitty commented Aug 8, 2024

Describe the bug
LDStreamingMode.streaming can cause start() / setOnline(true) to timeout behind some proxy servers.

We observe that 2% of our customers appear to be behind proxy servers that cause this issue. While cached flags values are available, falling back to polling mode is more reliable for these users.

To reproduce

Add device to a network with an incompatible proxy server and attempt start in streaming mode (which is default):

var config = LDConfig(mobileKey: "")
config.startOnline = false
config.streamingMode = .streaming
LDClient.start(config: config, context: context, startWaitSeconds: 5) { timedOut in
   ...
}

Request is sent to https://clientstream.launchdarkly.com and headers are returned but no data is ever received within the body, timeout occurs and completion handler is called.

Expected behavior
It would be great to detect this and switch to polling somehow.

It's unclear how one could try with streaming then fall back to polling. Its possible to use CFNetworkCopyProxiesForURL to detect upfront if the config.streamingURL will be handled via a proxy, this

Logs
If applicable, add any log output related to your problem.

Library version
9.8.2

XCode and Swift version
Xcode 15.4 Swift 5.10

Platform the issue occurs on
iOS

@tanderson-ld
Copy link
Contributor

tanderson-ld commented Aug 8, 2024

Hi @swhitty. We are currently working through some designs for supporting multiple datasources with prioritization and fallback mechanisms. We will keep your situation in mind as we work through those designs.

We definitely prefer customers to use streaming, but in your situation, could you help us understand why using polling is prohibitive?

Does your application get used in an environment where Proxies are more prevalent in your opinion? I don't know off the top of my head what the prevalence of Proxy usage in the iOS ecosystem is. If it is true that 2% of all global iOS users are using proxies, that is significant and we will want to dig more.

@swhitty
Copy link
Author

swhitty commented Aug 15, 2024

We prefer to use streaming because it works great for 97% of our users and is highly responsive in broadcasting changes.

We find that 3% of our users receive a timeout when attempting to connect Launch Darkly in streaming mode and therefore operate on cached flag values. We know that some of these users are behind a proxy server that appears to be incompatible with the Launch Darkly streaming connection.

We don't want to switch every user to polling, we would like to improve the experience for these 3% of users without degrading the experience for the 97% where it works great.

@swhitty
Copy link
Author

swhitty commented Oct 4, 2024

I've collected some data over the past month and 2.8% of our ~1M users have been behind a proxy server at least once.

@tanderson-ld
Copy link
Contributor

Thank you for that data point.

@tanderson-ld
Copy link
Contributor

How are you positively identifying that the customer is behind a proxy? Could you customize those customers to use polling if you can detect it beforehand as a workaround for the time being?

@swhitty
Copy link
Author

swhitty commented Oct 8, 2024

We are using CFNetworkCopyProxiesForURL to detect upfront if the config.streamingURL will be handled via a proxy and preemptively using polling for these users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants