-
-
Notifications
You must be signed in to change notification settings - Fork 736
Download with getData()
stalls for large file on slow network
#1156
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
Comments
Thanks for opening this issue!
|
getData()
call for large file on slow network.getData()
stalls for large file on slow network
getData()
stalls for large file on slow networkgetData()
stalls for large file on slow network
|
Providing more information below. First, when I wrote "hanging indefinitely", I meant that literally: the calling thread is blocked and never released. It's not about waiting a bit longer. That's the state of my
As a workaround, I refactored the code from calling
This resulted in this explicit
Then I tried to increase the timeouts of this custom OkHttpClient to 60 seconds (just like I tried with Parse's OkHttpClient), but the thread got stuck again. Just to be sure, I let the app run for another 10 minutes. Nothing. Similar picture in the thread dump:
As a last resort I tried to override the version of OkHttp used by Parse ( IMO, all this means that the problem is either in OkHttp, or my backend, or both. Even assuming that the backend misbehaves, OkHttp should throw TimeoutException instead of hanging, right? Empirically, I found that the threshold between TimeoutException and hanging is around 30 seconds (for timeout setting of 25 seconds I get the exception, but for 30 the thread gets stuck). I guess the next steps from my side should be:
Any additional ideas? |
In addition, @mtrezza, the new title you assigned to this issue can be misleading because I'm having troubles with downloading the data, not uploading. |
Is there a URL I can use to reproduce? What's your nginx version? |
@swankjesse , thanks for jumping in. I'm using Ngnix I wouldn't like to share our URLs here, so I'll PM a URL to a test file to you on Twitter. For your convenience, that's the minimal code sample that reproduces the problem on my end (regardless of Parse):
|
getData()
stalls for large file on slow networkgetData()
stalls for large file on slow network
getData()
stalls for large file on slow networkgetData()
stalls for large file on slow network
Thanks for noting and providing the additional details.
Yes I would say so. |
The label |
Ok, something interesting just happened: after I constructed the minimal test case for @swankjesse and sent the previous reply, my test case did throw TimeoutException:
However, as you can see from the timestamps, this happened after more than 4 minutes, even though the timeout is configured to 40 seconds. I wonder if this can be it: OkHttp doesn't hang, but the actual timeout is much longer than the specified configuration. |
There is definitely something to think about here. The actual timeout seems to be much higher than the configured timeout and this relationship isn't linear: At this point, I'm pretty sure that this has little to do with Android SDK. @mtrezza, please consider migrating this ticket to Parse Server (if that's an option). |
The URL you're downloading from is pointing to Parse Server or to a external source?
In which case could that be a Parse Server issue? The Parse Android SDK should ultimately decide for itself when to timeout. Or let the underlying HTTP lib timeout for it. |
@mtrezza , it's on Parse Server. I can send it to you via some private channel if you'd like to have a look yourself. |
Could it be that the timeout you are referring to means "time since last data package received" and on your slow network there keeps data trickling in and therefore the timeout never occurs but also the download completion is not reached yet after a long time? Did you monitor your network to see whether there are packets being transmitted? Again, I cannot see how it would mKe a difference from where the file is downloaded, the client controls when to timeout, not the server. |
Yep, readTimeout is the maximum delay between bytes received; callTimeout is the max duration for the whole call. |
@vzukanov Your read timeout is 40s in you example. You can test that by capping the connection between client and server during an ongoing data transfer and waiting for 40s. If you set a call timeout to for example 10s, you can verify that by slowing down the network so that it would take longer than 10s, but after 10s the timeout should already occur. My suspicion is that what you described as "hanging" is actually an ongoing data transfer at very slow speed. |
@mtrezza, I haven't reached down into TCP layer yet. Maybe tomorrow (hopefully we'll have a better hypothesis by then). Just to give a bit more context: I'm using Android emulator to throttle the network speed. This is the "highest" setting that still suffers from this problem: According to what I saw, HSDPA amounts to ~14000 Kbps. So, given this speed, a ~20MB file should be downloaded in ~12 seconds. That's not what I see. Now, piggy-backing on @swankjesse comment, we could hypothesize that there is some weird discontinuity in the stream of the data from the server, which leads to very long download times. However, it immediately rises two questions:
Out of curiousity I set the timeouts to 120 seconds and initiated the same flow. It's been downloading this file for about 30 minutes now and still didn't complete. Taking into account the fact that the same file is downloaded in ~8 seconds if I switch the emulator to LTE (~180000 kbps), I'd say there is something odd going on with either my Parse Server or Nginx or some other component. I just don't see how this can be explained by just "slow speed". We also experienced this problem on real devices connected to WiFi networks. So, if we rule out OkHttp as a contributor, what could cause something like what I see on Parse Server side? |
Nothing I can think of. A client has full autonomy over its decision to timeout. If you run your minimal example with a different URL, e.g. directly to where the file is stored, do you observe the same behavior? |
I couldn’t reproduce this with OkHttp on my desktop, either at full speed or throttled to 3G. The window update frames are perfect so I think that’s an unlikely culprit. full_speed_frames.txt Next best guess: the Android emulator might be hurting you here. |
@vzukanov Simulator is a good tip. Maybe try on a real device for comparison? If you enable the Developer menu in the Android settings, you may also be able to simulate a slow network. Otherwise you could connect to wifi and slow the network down for the device on the router side. |
So, @vzukanov to summary - the downloads stalls because of configuration outside the scope of this SDK? Do you think there's something to be adjusted here? |
Sorry, forgot to report back. So, that's what I think happened: |
New Issue Checklist
Issue Description
Parse Android SDK hangs when issuing
getData()
call for large file on slow network.Steps to reproduce
Store a large file in Parse and try to get its data synchronously (on background thread) using
getData()
call when a mobile device is connected to slow network (or slowed down emulator).Actual Outcome
getData()
call hangs indefinitely.Expected Outcome
getData()
should either succeed, or throw an exception.Environment
Parse Android SDK
3.0.0
Android 11
Server
5.1.1
Ubuntu 20.04
Digital Ocean
Database
MongoDB
3.6.8
Logs
Nginx last entry in
access.log
when Andorid SDK hangs on slow network:On faster network (LTE), I Nginx's
access.log
shows the following:Additional info
First, I thought that the problem is client-side timeout. So, I increased it:
Unfortunately, did not work.
Then I increased timeouts for Nginx:
Did not work either.
This is a critical problem for us. If Parse Android SDK would just throw an exception instead of hanging it would make the situtation much better.
The text was updated successfully, but these errors were encountered: