GithubHelp home page GithubHelp logo

[Bug] Storage PutFileAsync/PutBytesAsync stops transfering bytes after exactly 5 minutes, throws "Firebase.Storage.StorageException: The operation retry limit has been exceeded" after exactly 5 more minutes about firebase-unity-sdk HOT 9 CLOSED

TobiasWehrum avatar TobiasWehrum commented on June 26, 2024
[Bug] Storage PutFileAsync/PutBytesAsync stops transfering bytes after exactly 5 minutes, throws "Firebase.Storage.StorageException: The operation retry limit has been exceeded" after exactly 5 more minutes

from firebase-unity-sdk.

Comments (9)

paulinon avatar paulinon commented on June 26, 2024

Hi @TobiasWehrum,

Does setting MaxUploadRetryTime to a higher value make a difference? You may use this code to have a maximum upload retry time of one hour:

storage.MaxUploadRetryTime = new TimeSpan(TimeSpan.TicksPerHour);

If that doesn't work, could you provide a minimal, reproducible example of your implementation so that we can identify what's causing this to happen?

from firebase-unity-sdk.

TobiasWehrum avatar TobiasWehrum commented on June 26, 2024

@paulinon When I tested that yesterday (with new TimeSpan(1, 0, 0)) the only difference it made was how long it took to throw Firebase.Storage.StorageException: The operation retry limit has been exceeded after it stopped uploading at the 5 minute mark.

I'll make an example later.

from firebase-unity-sdk.

TobiasWehrum avatar TobiasWehrum commented on June 26, 2024

@paulinon, here is how to reproduce the problem using Unity 2022.3.17f1 on Windows 10 in the editor. I get a 100% reproduction rate on this.

  1. Make an empty project.
  2. Add FirebaseStorage.unitypackage version 11.6.0 or 11.7.0 (I tested both).
  3. Deactivate "Validate References" in the inspector for Assets/ExternalDependencyManager/Editor/1.2.179/Google.IOSResolver.dll and Assets/Firebase/Editor/Firebase.Editor.dll to resolve the errors in the Console.
  4. Create or reuse a Firebase project with a storage component and at least one folder with writing permissions set to if true.
  5. Add that project's google-services.json to the project.
  6. Add UploadTest.cs (below) to the project.
  7. Open the example scene.
  8. Create an empty GameObject and attach UploadTest as a component.
  9. Fill out UploadTest:
  • firebaseStorageUrl should point to your bucket, e.g. gs://my-app-name.appspot.com
  • storagePathStringForUpload should point to a place inside a folder with if true writing permissions, e.g. bugtest/testfile
  • localFilePathForUpload should point to a file that is big enough that the upload will take longer than 5 minutes (e.g. 423 MB for me), e.g. C:\bigfile.mp4.
  1. Run the scene for 10 minutes and observe the console output:
  • At 05:00 it will stop transfering bytes.
  • A long time later on it might or might not restart for a bit (in the log below at 09:29, in another test it happened at 09:57).
  • Around 10:01 it will throw StorageException: The operation retry limit has been exceeded..
  1. Bonus step: After the StorageException, stop the player, and close Unity. Most of the time Unity will crash.

If you try step 10 again while commenting in the second PutFileAsync block in UploadTest.cs, you can observe that any new call to PutFileAsync after the StorageException: The operation retry limit has been exceeded. will immediately freeze the Unity Editor. In the build it would probably crash.

Example log output excerpt:

Database URL not set in the Firebase config.
[00:00:00] Transfered: 0 of 433315522 bytes
[00:00:00] Transfered: 65536 of 433315522 bytes
[00:00:01] Transfered: 131072 of 433315522 bytes
[00:00:02] Transfered: 196608 of 433315522 bytes
[...]
[00:04:54] Transfered: 29753344 of 433315522 bytes
[00:04:55] Transfered: 29818880 of 433315522 bytes
[00:04:56] Transfered: 29884416 of 433315522 bytes
[00:04:56] Transfered: 29949952 of 433315522 bytes
[00:04:57] Transfered: 30015488 of 433315522 bytes
[00:04:57] Transfered: 30081024 of 433315522 bytes
[00:04:58] Transfered: 30146560 of 433315522 bytes
[00:04:58] Transfered: 30212096 of 433315522 bytes
[00:04:59] Transfered: 30277632 of 433315522 bytes
[00:05:00] Transfered: 30343168 of 433315522 bytes
[00:05:01] Transfered: 30343168 of 433315522 bytes
[00:05:01] Transfered: 30343168 of 433315522 bytes
[00:05:02] Transfered: 30343168 of 433315522 bytes
[00:05:03] Transfered: 30343168 of 433315522 bytes
[00:05:04] Transfered: 30343168 of 433315522 bytes
[00:05:04] Transfered: 30343168 of 433315522 bytes
[00:05:05] Transfered: 30343168 of 433315522 bytes
[00:05:06] Transfered: 30343168 of 433315522 bytes
[...]
[00:09:23] Transfered: 30343168 of 433315522 bytes
[00:09:23] Transfered: 30343168 of 433315522 bytes
[00:09:24] Transfered: 30343168 of 433315522 bytes
[00:09:24] Transfered: 30343168 of 433315522 bytes
[00:09:25] Transfered: 30343168 of 433315522 bytes
[00:09:26] Transfered: 30343168 of 433315522 bytes
[00:09:26] Transfered: 30343168 of 433315522 bytes
[00:09:27] Transfered: 30343168 of 433315522 bytes
[00:09:27] Transfered: 30343168 of 433315522 bytes
[00:09:28] Transfered: 30343168 of 433315522 bytes
[00:09:29] Transfered: 30343168 of 433315522 bytes
[00:09:29] Transfered: 30408704 of 433315522 bytes
[00:09:30] Transfered: 30474240 of 433315522 bytes
[00:09:30] Transfered: 30539776 of 433315522 bytes
[00:09:31] Transfered: 30605312 of 433315522 bytes
[00:09:31] Transfered: 30670848 of 433315522 bytes
[00:09:32] Transfered: 30736384 of 433315522 bytes
[00:09:32] Transfered: 30801920 of 433315522 bytes
[00:09:33] Transfered: 30867456 of 433315522 bytes
[...]
[00:09:57] Transfered: 33619968 of 433315522 bytes
[00:09:58] Transfered: 33685504 of 433315522 bytes
[00:09:58] Transfered: 33751040 of 433315522 bytes
[00:09:59] Transfered: 33816576 of 433315522 bytes
[00:09:59] Transfered: 33882112 of 433315522 bytes
[00:10:00] Transfered: 33947648 of 433315522 bytes
[00:10:01] Transfered: 34013184 of 433315522 bytes
StorageException: The operation retry limit has been exceeded.

UploadTest.cs:

using System;
using System.Threading;
using Firebase;
using Firebase.Storage;
using UnityEngine;

public class UploadTest : MonoBehaviour
{
    [SerializeField] private string firebaseStorageUrl;
    [SerializeField] private string storagePathStringForUpload;
    [SerializeField] private string localFilePathForUpload;

    private CancellationTokenSource cancellationTokenSource;

    protected async void Awake()
    {
        var depencencyResult = await FirebaseApp.CheckAndFixDependenciesAsync();
        if (depencencyResult != DependencyStatus.Available)
        {
            Debug.LogError("FirebaseApp.CheckAndFixDependenciesAsync failed.");
            return;
        }

        var storage = FirebaseStorage.DefaultInstance;
        var storageRef = storage.GetReferenceFromUrl(firebaseStorageUrl);

        cancellationTokenSource = new CancellationTokenSource();

        var startTime = Time.realtimeSinceStartup;

        var progressHandler = new StorageProgress<UploadState>(state =>
        {
            var currentTime = TimeSpan.FromSeconds(Mathf.FloorToInt(Time.realtimeSinceStartup - startTime));
            Debug.Log($"[{currentTime}] Transfered: {state.BytesTransferred} of {state.TotalByteCount} bytes");
        });

        try
        {
            await storageRef.Child(storagePathStringForUpload).PutFileAsync(localFilePathForUpload, null, progressHandler, cancellationTokenSource.Token, null);

            Debug.Log("Upload finished");
        }
        catch (Exception e)
        {
            Debug.LogError(e);
        }

        /*
        // If you comment this block in, Unity will freeze immediately when calling PutFileAsync() (after the previous block failed with a StorageException).
        // Editor.log will only show a single line before ending abruptly:
        // ERROR: ret == ((((DWORD )0x00000000L) ) + 0 )
        try
        {
            await storageRef.Child(storagePathStringForUpload).PutFileAsync(localFilePathForUpload, null, progressHandler, cancellationTokenSource.Token, null);

            Debug.Log("Upload finished");
        }
        catch (Exception e)
        {
            Debug.LogError(e);
        }
        */

        cancellationTokenSource = null;
    }

    protected void OnDestroy()
    {
        if (cancellationTokenSource != null)
        {
            cancellationTokenSource.Cancel();
            cancellationTokenSource = null;
        }
    }
}

from firebase-unity-sdk.

paulinon avatar paulinon commented on June 26, 2024

Hi @TobiasWehrum,

Thanks for the additional information. I was able to reproduce the issue, and it persists even after setting the upload retry time. That said, I'll be relaying my observations to our team. You may refer to this thread for updates.

from firebase-unity-sdk.

TobiasWehrum avatar TobiasWehrum commented on June 26, 2024

Thank you, @paulinon - looking forward to this getting resolved.

On a related note, I think the same bug might apply not just to uploading, but also to downloading. I didn't have time to investigate yet, but yesterday I observed a particularly big download on a slow internet connection that seemed to stop after about 5 minutes, and then threw a StorageException: The operation retry limit has been exceeded. not long after.

from firebase-unity-sdk.

TobiasWehrum avatar TobiasWehrum commented on June 26, 2024

@paulinon I just tested it to confirm it: Literally the same (stops transfering after 5 minutes, operation retry limit StorageException at 10 minutes) happens when downloading via GetFileAsync.

from firebase-unity-sdk.

a-maurice avatar a-maurice commented on June 26, 2024

This should be fixed with the latest release, https://github.com/firebase/firebase-unity-sdk/releases/tag/v11.9.0
The 5 minute timeout was the default set by Curl, so we just adjusted that.

from firebase-unity-sdk.

TobiasWehrum avatar TobiasWehrum commented on June 26, 2024

@a-maurice Thanks for the fix and the info what it was!

It doesn't sound like the curl timeout should lead to the observed crashes/freezes though. There might be a secondary bug here that could occur under other conditions too, like e.g. when "The operation retry limit has been exceeded" is thrown for other reasons.

from firebase-unity-sdk.

a-maurice avatar a-maurice commented on June 26, 2024

Yeah, it is certainly possible, and we will keep an eye out for possible fixes for that.

from firebase-unity-sdk.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.