Search Unity

[bug] bundle.LoadAssetAsync can complete just inplace

Discussion in 'Addressables' started by nik_d, Jun 12, 2019.

  1. nik_d

    nik_d

    Joined:
    Apr 27, 2018
    Posts:
    66
    workaround:
    in BundledAssetProvider.cs Start(...)
    Code (CSharp):
    1.                     //**addressables: bugfix: possible to be completed just here and provideHandle became invalid then
    2.                     provideHandle.SetProgressCallback(ProgressCallback);
    3.                    
    4.                     m_RequestOperation.completed += ActionComplete;
    5.                     //provideHandle.SetProgressCallback(ProgressCallback);
    and in ProviderOperation.cs Progress get

    Code (CSharp):
    1.                 if (m_GetProgressCallback == null)
    2.                     //return 0.5f;
    3.                     //**addressables: bugfix: return full completeness for succeed operation after ProviderCompleted (m_NeedsRelease contains status)
    4.                     return m_NeedsRelease ? 1.0f: 0.0f;
     
  2. nik_d

    nik_d

    Joined:
    Apr 27, 2018
    Posts:
    66
    missed changes in AssetBundleProvider.cs Start(...):

    Code (CSharp):
    1.             //**addressables: bugfix: setup before BeginOperation - read details below
    2.             provideHandle.SetProgressCallback(PercentComplete);
    3.            
    4.             BeginOperation();
    5.            
    6.             //**addressables: bugfix: if m_RequestOperation.completed is called just inside BeginOperation, then provideHandle is completed (version changed)
    7.             //    and SetProgressCallback throws exception "The ProvideHandle is invalid. After the handle has been completed, it can no longer be used"
    8.             //    and correctly completed operation (either LoadFromFileAsync or SendWebRequest) fails!
    9.             //provideHandle.SetProgressCallback(PercentComplete);
     
  3. thedred112

    thedred112

    Joined:
    Jul 15, 2013
    Posts:
    2
    have you make a bug report?
     
  4. nik_d

    nik_d

    Joined:
    Apr 27, 2018
    Posts:
    66
    Sorry, no. Good bug report requires to create sample test-case.. a lot of time to waste after it's already fixed.
    All such bugs I repair by myself in big project where it was found and at least write about them here =).
     
    tonialatalo likes this.
  5. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    I appreciate the bug info and fix, but could you please add a little more context so we are sure to not misunderstand what you are fixing? What exact scenario is broken? "[bug] bundle.LoadAssetAsync can complete just inplace" Does that mean it can in theory, but it isn't now, so the fix makes it do that? Or it can now, but it shouldn't, so the fix stops it?
     
  6. nik_d

    nik_d

    Joined:
    Apr 27, 2018
    Posts:
    66
    It still really happens, just checked in the simple sample. Depends on the speed of UnityWebRequestAssetBundle.
    To reproduce - make two LoadAssetAsync in a row:
    Code (CSharp):
    1.     private IEnumerator Start()
    2.     {
    3.         yield return Addressables.LoadAssetAsync<GameObject>("Canvas");
    4.         yield return Addressables.LoadAssetAsync<GameObject>("Canvas");
    5.     }
    6.  
    To emulate "fast" request and reproduce repeat with absolute probability - put
    Thread.Sleep(1000);
    in AssetBundleProvider.cs after
    m_RequestOperation = req.SendWebRequest();
    :
    Code (CSharp):
    1.                 m_RequestOperation = req.SendWebRequest();
    2.                 Thread.Sleep(1000);
    3.                 m_RequestOperation.completed += WebRequestOperationCompleted;
    4.  
    In the attach - the simplest project: open Scenes/SampleScene.unity, switch to "Packed Mode", "Build Player Content", "Play". Result:

    Code (CSharp):
    1. Exception: Attempting to use an invalid operation handle
    2. UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.get_InternalOp () (at Library/PackageCache/com.unity.addressables@1.1.9/Runtime/ResourceManager/AsyncOperations/AsyncOperationHandle.cs:258)
    3. UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle.get_Status () (at Library/PackageCache/com.unity.addressables@1.1.9/Runtime/ResourceManager/AsyncOperations/AsyncOperationHandle.cs:322)
    4. UnityEngine.ResourceManagement.AsyncOperations.GroupOperation.CompleteIfDependenciesComplete () (at Library/PackageCache/com.unity.addressables@1.1.9/Runtime/ResourceManager/AsyncOperations/GroupOperation.cs:56)
    5. UnityEngine.ResourceManagement.AsyncOperations.GroupOperation.OnOperationCompleted (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle op) (at Library/PackageCache/com.unity.addressables@1.1.9/Runtime/ResourceManager/AsyncOperations/GroupOperation.cs:102)
    6. DelegateList`1[T].Invoke (T res) (at Library/PackageCache/com.unity.addressables@1.1.9/Runtime/ResourceManager/Util/DelegateList.cs:69)
    7. UnityEngine.Debug:LogException(Exception)
    8. DelegateList`1:Invoke(AsyncOperationHandle) (at Library/PackageCache/com.unity.addressables@1.1.9/Runtime/ResourceManager/Util/DelegateList.cs:73)
    9. UnityEngine.AsyncOperation:InvokeCompletionEvent()
    10.  
     

    Attached Files:

    tonialatalo likes this.
  7. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    Ah, I see. The issue is that the op can finish too quickly. Have you tried this with 1.1.9? A too-fast-op was what was also causing failed downloads to remain in the op cache forever. This note from the changelog:
    Fixed issue where failed async operations weren't getting released from the async operation cache

    Not sure if that fix will solve for what you posted about, but it may. If not, we definitely want to get it cleaned up.
     
  8. nik_d

    nik_d

    Joined:
    Apr 27, 2018
    Posts:
    66
    Yes, the sample I've tried was on Unity 2019.2.1f1 with addressables 1.1.9.
    To surely reproduce it - just put
    Thread.Sleep(1000);
    after
    m_RequestOperation = req.SendWebRequest();
    in AssetBundleProvider.cs
     
  9. TheZkip

    TheZkip

    Joined:
    Feb 21, 2013
    Posts:
    3
    Can confirm this too. Addressables version 1.1.9, Unity 2018.4.6f1.

    I had this issue running on WebGL and nik_d's workaround removed my "ProvideHandle invalid" exceptions. Without the fix first asset loads would be ok but a second load op after Release would throw exceptions. If I understood docs correctly the asset/bundle is not actually unloaded on Release (even if ref count goes to 0). I guess then the second "load" would just fetch the asset from memory which would then be 'too-fast' and cause the ProvideHandle to be invalid?
     
    tonialatalo likes this.
  10. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    Thanks for letting us know, we'll get that cleaned up.
     
    tonialatalo and Overing like this.
  11. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,091
    Still bugged in 1.2.4
     
  12. tonialatalo

    tonialatalo

    Joined:
    Apr 23, 2015
    Posts:
    60
    I get that you got a hold of this, no bug report or anything needed?

    I also encountered this in current (1.2.4), and nik_d's fix solved it (thanks a ton for sharing!)

    In my case, it is with WebGL, I think when the asset is already in browser cache (local storage i guess). First time loading worked. Then when e.g. opening the app again, it failed. After clearing local storage, worked again. Once. I guess the op is sync in the browser in the sense that it succeeds immediately when the data is already in cache.
     
  13. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,091
    I don't recommend using Addressables in WebGL in production. For me it gave very unpredictable results. Everything worked fine and suddenly after one build project started to eat huge amounts of memory and to crash the browser.
     
    mandisaw likes this.
  14. davidla_unity

    davidla_unity

    Unity Technologies

    Joined:
    Nov 17, 2016
    Posts:
    763
    Can anyone confirm if they're still seeing this in 1.3.8 or above? I believe we've fixed all the places where we were trying to use the operation handle after it completed but I just want to make sure.
     
  15. Meyham_233

    Meyham_233

    Joined:
    Jun 16, 2020
    Posts:
    1
    Sorry if answering an old thread is inappropriate, but I found this one on google and nik_d's workaround was still needed for me in Addressables version 1.10.
     
  16. davidla_unity

    davidla_unity

    Unity Technologies

    Joined:
    Nov 17, 2016
    Posts:
    763
    @Meyham_233 Can you say which of the fixes were still needed in 1.10? nik_d gives a couple different fixes, most of which were already implemented by that version. The only one not implemented was ProviderOperation.cs Progress and only because that changed drastically from that code.

    Alternatively, have you updated your Addressable version since then? If so are you still having any of these issues?
     
  17. felipe-shida-playkids

    felipe-shida-playkids

    Joined:
    Sep 16, 2020
    Posts:
    13
    @DavidUnity3d I'm still seeing "Exception: Attempting to use an invalid operation handle" on BundledAssetProvider:89 where an async op with an outdated version is accessed by an async op handle.

    I'm running Unity 2019.4.15 and Addressables 1.16.13
     
  18. msfredb7

    msfredb7

    Joined:
    Nov 1, 2012
    Posts:
    163
    If anybody else like me is encountering the "Attempting to use an invalid operation handle" issue even with recent Addressables versions, make sure Addressables.Release(handle) is not called twice with the same handle somewhere in your code.

    In my case, it was causing the refcount to decrease to zero while other handles were using it.
     
    CharBodman likes this.