Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Git timeout on large remote push or pull -- possibly using wrong setting #1063

@sna-scourtney

Description

@sna-scourtney

Description

Attempting to push a large commit, such as from the initial import of a project, can fail due to a ProcessException thrown because of a timeout.

I attempted to fix the timeout by increasing the Web Timeout and Git Timeout in the settings UI, but even setting each of these to 1000000 (equivalent to 1000 seconds) still produced the timeout.

Examination of the source code suggests the user-entered settings may not be respected. From the file src/GitHub.Api/Tasks/ProcessTask.cs, the conditional at line 166 uses ApplicationConfiguration.DefaultGitTimeout:

                if (Process.StartInfo.CreateNoWindow)
                {
                    bool done = false;
                    while (!done)
                    {
                        var exited = WaitForExit(500);
                        if (exited)
                        {
                            // process is done and we haven't seen output, we're done
                            done = !gotOutput.WaitOne(100);
                        }
                        else if (token.IsCancellationRequested || (taskName.Contains("git lfs") && lastOutput.AddMilliseconds(ApplicationConfiguration.DefaultGitTimeout) < DateTimeOffset.UtcNow))
                        // if we're exiting or we haven't had output for a while
                        {
                            Stop(true);
                            token.ThrowIfCancellationRequested();
                            throw new ProcessException(-2, "Process timed out");
                        }
                    }

The UI setting, however, is not stored in DefaultGitTimeout but rather in GitTimeout. Here is the code from src/GitHub.Api/Application/ApplicationConfiguration.cs:

namespace GitHub.Unity
{
    public static class ApplicationConfiguration
    {
        public const int DefaultWebTimeout = 3000;
        public const int DefaultGitTimeout = 5000;
        public static int WebTimeout { get; set; } = DefaultWebTimeout;
        public static int GitTimeout { get; set; } = DefaultGitTimeout;
    }
}

Finally, here's the setting code from ..../UI/SettingsView.cs:

            gitTimeout = ApplicationConfiguration.GitTimeout;
            EditorGUI.BeginChangeCheck();
            {
                gitTimeout = EditorGUILayout.IntField(GitTimeoutLabel, gitTimeout);
            }
            if (EditorGUI.EndChangeCheck())
            {
                ApplicationConfiguration.GitTimeout = gitTimeout;
                Manager.UserSettings.Set(Constants.GitTimeoutKey, gitTimeout);
            }

I will note in passing that there is no Tooltip attribute on either of the timeout fields (web and git), so it may not be evident to people that these are milliseconds and not seconds. It would probably be good to add those as a minor enhancement.

Steps to Reproduce

  1. Create an empty project on an LFS-capable remote such as GitHub or GitLab.
  2. Install GitHub for Unity into a previously-untracked Unity project of nontrivial size.
  3. Initialize GH4U and set up the remote.
  4. Set the timeout values in the GH4U settings to a large value such as 1000000.
  5. Push the initial commit to the remote and verify that this worked.
  6. Commit and attempt to push a large change to the repository, in the gigabyte range.

Expected behavior: All of the files should be pushed to the remote.

Actual behavior: The transaction times out partway through, leaving the remote in a inconsistent state.

Reproduces how often: I can reproduce this reliably as long as the changes being pushed are sufficiently large so the transaction time exceeds the default limit.

Additional Information

Here is an excerpt from the trace log:

ProgramData:C:\ProgramData
 ---> GitHub.Unity.ProcessException: Process timed out
  at GitHub.Unity.ProcessWrapper.Run () [0x001d9] in C:\projects\unity\src\GitHub.Api\Tasks\ProcessTask.cs:171
   --- End of inner exception stack trace ---
  at GitHub.Unity.ProcessTaskWithListOutput`1+<>c__DisplayClass20_0[T].<RunWithReturn>b__1 () [0x000e6] in C:\projects\unity\src\GitHub.Api\Tasks\Proces
sTask.cs:506
  at GitHub.Unity.ProcessWrapper.Run () [0x003cd] in C:\projects\unity\src\GitHub.Api\Tasks\ProcessTask.cs:206
  at GitHub.Unity.ProcessTaskWithListOutput`1[T].RunWithReturn (System.Boolean success) [0x00061] in C:\projects\unity\src\GitHub.Api\Tasks\ProcessTask.
cs:513
  at GitHub.Unity.TaskBase`1[TResult].RunSynchronously () [0x00049] in C:\projects\unity\src\GitHub.Api\Tasks\TaskBase.cs:685
  at System.Threading.Tasks.Task`1[TResult].InnerInvoke () [0x0000f] in <1f0c1ef1ad524c38bbc5536809c46b48>:0
  at System.Threading.Tasks.Task.Execute () [0x00010] in <1f0c1ef1ad524c38bbc5536809c46b48>:0
GitHub.Unity.ProcessException: Process timed out
  at GitHub.Unity.ProcessWrapper.Run () [0x001d9] in C:\projects\unity\src\GitHub.Api\Tasks\ProcessTask.cs:171

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions