Search Unity

UnityWebRequest.Send() stalls

Discussion in 'Web' started by sirrus, Jun 12, 2017.

  1. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    We have a wrapper class that processes AssetBundles and uses the UnityWebRequest to perform the download operation like this:

    Code (CSharp):
    1.  
    2. using (UnityWebRequest www = UnityWebRequest.GetAssetBundle(url, (uint)version, 0))
    3.             {
    4.                    Debug.Log("::: getting " + url + ", v" + version);
    5.  
    6. // adds request headers here...
    7.  
    8.                 yield return www.Send();
    9.                
    10.                 Debug.Log("::: got " + url + ", v" + version);
    11.  
    12. // error handling, downloadHandler usage, etc...
    13.  
    14.             }
    15.  
    In the Editor, we make many (hundreds) of these calls and everything works as expected. However, when testing it in a WebGL build, typically in the 2nd session, the .Send() call simply stalls at certain assetbundles.

    We noticed this previously when the call was made twice for the same assetbundle/url but there is no duplication in this case. I assume it is preparing to load from cache but it provides no error, no network request and the downloadProgress is always -1 which according to documentation means that .Send() isnt even called yet.

    Has anyone experienced this or have an idea as to what might cause it?
     
  2. kognito1

    kognito1

    Joined:
    Apr 7, 2015
    Posts:
    331
    I have a similar issue while trying to download too many asset bundles simultaneously (5 in our case), but that happens even in the editor (rare, but can happen). The UnityWebRequest basically never starts after calling send (progress never moves beyond 0). The request will either hang forever or eventually throw an error. I resolved it by adding my own timeout logic and if the progress is still 0 after the timeout I just abort and retry the request. It happens so rarely for us that this is an acceptable workaround.

    I never have this problem if I download one asset bundle at a time so I think it's something to do with loading many of them simultaneously. At any rate, it happens in the editor for me so I don't think a webgl bug, but a UnityWebRequest bug.
     
  3. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    I thought that might be the case so have actually throttled the requests but that didnt seem to change the outcome. I agree that it is probably a UWR bug but just rears its head for us consistently in WebGL - which is why I posted it here.

    Ill give the workaround a shot, thanks!
     
  4. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Well, so far no workaround has worked. We abort the UnityWebRequest if it times out and it still hangs (based on dox, .Abort() waits for .Send() to be called anyway). We also tried loading assetbundles one at a time and it still hangs on the .Send()...
     
  5. kognito1

    kognito1

    Joined:
    Apr 7, 2015
    Posts:
    331
    You can't yield on send to do the workaround, you need to constantly check the UnityWebRequest's progress in a corountine or the update loop. Something like this:

    Code (CSharp):
    1. while(urw is not done)
    2. {
    3.     if (we timeout)
    4.     {
    5.         if (urw.downloadProgress == 0.0f)
    6.         {
    7.             urw.Abort();
    8.             yield return null;
    9.             yield return null;
    10.             yield return null;
    11.             urw.Dispose();
    12.             urw = null;
    13.             urw = UnityWebRequest.GetAssetBundle([web path], 0);
    14.             urw.Send();
    15.             [reset timeout window and keep waiting]
    16.         }
    17.         else
    18.         {
    19.             [throw real error]
    20.         }
    21.     }
    22.     else
    23.     {
    24.         yield return null;
    25.     }
    26. }
     
  6. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
  7. kognito1

    kognito1

    Joined:
    Apr 7, 2015
    Posts:
    331
    Then we have a different problem, my uwr gets stuck on 0, not -1.
     
  8. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Im beginning to think it is WebGL specific because it only seems to happen when assets are loaded from cache in the browser.

    It looks like *every* UWR assetbundle request gets stuck on .Send() with a -1 downloadProgress value. The timeout retry does eventually seem to work but since it's timing out on every single call, it doesn't really help. Ill keep digging...
     
  9. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Well, I've wasted an entire day on troubleshooting this. Here's my conclusion:

    Making several (say 15) AssetBundle requests around the same time using UnityWebRequest w/request headers works fine the first time. Subsequent loads in WebGL of the same assetbundles seem to fail. I have to surmise that it is failing when loading the cached data from disk.

    Replacing the exact same calls with the WWW API works as intended for all sessions in WebGL. :(
     
  10. kognito1

    kognito1

    Joined:
    Apr 7, 2015
    Posts:
    331
    I vaguely remember you guys use the "better" asset bundle caching (CachedXMLHttpRequest), maybe you're hitting a bug there? Does it still happen when you use just LoadFromCacheOrDownload?
     
  11. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Correct, but we have removed the CachedXMLHttpRequest plugin for the UWR tests, so it shouldnt be a factor. I don't dare go back to LoadFromCacheOrDownload at this point.

    WWW with the plugin is/was working fine, but I assume it will be deprecated at some point and wanted to upgrade everything to the newer API.
     
  12. kognito1

    kognito1

    Joined:
    Apr 7, 2015
    Posts:
    331
    So just to be clear, any combination of UWR (not cached, "builtin unity caching", CachedXMLHttpRequest caching) doesn't work? And any combination of WWW (not cached, "builtin unity caching", CachedXMLHttpRequest caching) works? I now wonder if we are in fact experiencing the same "general UWR bug" but in different ways.
     
  13. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Specifically referring to the UWR GetAssetBundle() API:

    - initial calls work in WebGL
    - subsequent calls to the same "URL" (which according to browser, tries to load the data from cache) stalls
    - that is both with and w/o CachedXMLHttpRequest in use

    With the WWW API:

    - initial calls work in WebGL
    - subsequent calls to the same "URL" (typically cached) also work
    - that is both with and w/o CachedXMLHttpRequest but obviously relies on browser caching if the plugin is not used

    Does that match your experience with UWR? You mentioned your timeout workaround and that has not really solved the problem for us, unfortunately.
     
  14. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Just saw this in a patch release (5.6.1p2):

    (895810) - WebGL: Fixed unresponsiveness when loading cashed AssetBundles with WWW.LoadFromCacheOrDownload

    I have not had a chance to test this but I wonder if it also fixes our UWR issues?
     
  15. kognito1

    kognito1

    Joined:
    Apr 7, 2015
    Posts:
    331
    I haven't used WWW in a long time so I can't be 100% sure my problem is a UWR only bug, but my "stall issue" happens even without caching so I guess I'm back to thinking my issue is different.
     
  16. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Well, FWIW, upgrading to 5.6.1p4 seems to have fixed the issue. UWR.Send() no longer stalls for asset bundles.
     
  17. sang

    sang

    Joined:
    Jul 17, 2013
    Posts:
    10
    I'm having the exact problem but with my editor and some Android users report similar symptom too (not sure about the later part) so I'm switching back to WWW.LoadFromCacheOrDownload. My version is 5.5.4.

    It was working fine until today.
     
  18. YoungXi

    YoungXi

    Joined:
    Jun 5, 2013
    Posts:
    63
    Hi all,

    I'm having the exact same problem.
    Even my computer stops reacting when it happens. It happend when Im trying to download multiple assetbundles.

    And I think the reason is that coroutine is not like thread. So the best way to solve this is to use Threading instead of built-in WWW class.

    Better to create async request to download the bytes and then load with Assetbundle.LoadFromMemory.

    While doing that , one should also create a custom caching system as well.

    Haven't tried that out, but soon I will find out.
     
  19. AlexHell

    AlexHell

    Joined:
    Oct 2, 2014
    Posts:
    167