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:
    50
    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:
    50
    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:
    50
    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

    Unity Technologies

    Joined:
    Apr 11, 2017
    Posts:
    954
    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:
    50
    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

    Unity Technologies

    Joined:
    Apr 11, 2017
    Posts:
    954
    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:
    50
    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

    Unity Technologies

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

    Kamyker

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

    tonialatalo

    Joined:
    Apr 23, 2015
    Posts:
    18
    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:
    72
    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.