• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

KSP-CKAN / CKAN / 15834236157

23 Jun 2025 07:42PM UTC coverage: 42.232% (+0.1%) from 42.099%
15834236157

push

github

HebaruSan
Merge #4398 Exception handling revamp, parallel multi-host inflation

3880 of 9479 branches covered (40.93%)

Branch coverage included in aggregate %.

48 of 137 new or added lines in 30 files covered. (35.04%)

12 existing lines in 6 files now uncovered.

8334 of 19442 relevant lines covered (42.87%)

0.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/GUI/Main/MainDownload.cs
1
using System;
2
using System.Linq;
3
using System.Collections.Generic;
4
using System.ComponentModel;
5
using System.Threading;
6
using System.Threading.Tasks;
7

8
using CKAN.GUI.Attributes;
9

10
namespace CKAN.GUI
11
{
12
    public partial class Main
13
    {
14
        private NetAsyncModulesDownloader? downloader;
15

16
        private void ModInfo_OnDownloadClick(GUIMod gmod)
17
        {
×
18
            StartDownload(gmod);
×
19
        }
×
20

21
        public void StartDownloads(IEnumerable<GUIMod> modules)
22
        {
×
23
            ShowWaitDialog();
×
24
            if (downloader != null)
×
25
            {
×
NEW
26
                Task.Run(() =>
×
27
                {
×
28
                    // Just pass to the existing worker
29
                    downloader.DownloadModules(modules.Select(m => m.ToModule()));
×
30
                });
×
31
            }
×
32
            else
33
            {
×
34
                // Start up a new worker
35
                Wait.StartWaiting(CacheMods, PostModCaching, true, modules.ToArray());
×
36
            }
×
37
        }
×
38

39
        public void StartDownload(GUIMod module)
40
        {
×
41
            StartDownloads(Enumerable.Repeat(module, 1));
×
42
        }
×
43

44
        [ForbidGUICalls]
45
        private void CacheMods(object? sender, DoWorkEventArgs? e)
46
        {
×
47
            if (e != null
×
48
                && e.Argument is ICollection<GUIMod> modules
49
                && Manager?.Cache != null)
50
            {
×
51
                var cancelTokenSrc = new CancellationTokenSource();
×
52
                Wait.OnCancel += cancelTokenSrc.Cancel;
×
53
                downloader = new NetAsyncModulesDownloader(currentUser, Manager.Cache, userAgent,
×
54
                                                           cancelTokenSrc.Token);
55
                downloader.DownloadProgress += OnModDownloading;
×
56
                downloader.StoreProgress    += OnModValidating;
×
57
                downloader.OverallDownloadProgress += currentUser.RaiseProgress;
×
58
                for (bool done = false; !done; )
×
59
                {
×
60
                    try
61
                    {
×
62
                        downloader.DownloadModules(modules.Select(m => m.ToModule()));
×
63
                        done = true;
×
64
                    }
×
65
                    catch (ModuleDownloadErrorsKraken k)
×
66
                    {
×
67
                        DownloadsFailedDialog? dfd = null;
×
68
                        Util.Invoke(this, () =>
×
69
                        {
×
70
                            dfd = new DownloadsFailedDialog(
×
71
                                Properties.Resources.ModDownloadsFailedMessage,
72
                                Properties.Resources.ModDownloadsFailedColHdr,
73
                                Properties.Resources.ModDownloadsFailedAbortBtn,
74
                                k.Exceptions.Select(kvp => new KeyValuePair<object[], Exception>(
×
75
                                    modules.Select(m => m.ToModule()).ToArray(), kvp.Value)),
×
76
                                (m1, m2) => (m1 as CkanModule)?.download == (m2 as CkanModule)?.download);
×
77
                             dfd.ShowDialog(this);
×
78
                        });
×
79
                        var skip  = (dfd?.Wait()?.OfType<CkanModule>() ?? Enumerable.Empty<CkanModule>())
×
80
                                                 .ToArray();
81
                        var abort = dfd?.Abort ?? false;
×
82
                        dfd?.Dispose();
×
83
                        if (abort || skip.Length > 0)
×
84
                        {
×
85
                            throw new CancelledActionKraken();
×
86
                        }
87
                    }
×
88
                }
×
89
                e.Result = e.Argument;
×
90
            }
×
91
        }
×
92

93
        public void PostModCaching(object? sender, RunWorkerCompletedEventArgs? e)
94
        {
×
95
            if (downloader != null)
×
96
            {
×
97
                downloader = null;
×
98
            }
×
99
            // Can't access e.Result if there's an error
100
            if (e?.Error != null)
×
101
            {
×
102
                switch (e.Error)
×
103
                {
104

105
                    case CancelledActionKraken:
106
                        // User already knows they cancelled, get out
107
                        HideWaitDialog();
×
108
                        EnableMainWindow();
×
109
                        break;
×
110

111
                    default:
112
                        FailWaitDialog(Properties.Resources.DownloadFailed,
×
113
                                       e.Error.Message,
114
                                       Properties.Resources.DownloadFailed);
115
                        break;
×
116

117
                }
118
            }
×
119
            else
120
            {
×
121
                // Close progress tab and switch back to mod list
122
                HideWaitDialog();
×
123
                EnableMainWindow();
×
124
                ModInfo.SwitchTab("ContentTabPage");
×
125
            }
×
126
        }
×
127

128
        [ForbidGUICalls]
129
        private void UpdateCachedByDownloads(CkanModule? module)
130
        {
×
131
            var allGuiMods = ManageMods.AllGUIMods();
×
132
            var affectedMods =
×
133
                module?.GetDownloadsGroup(allGuiMods.Values
134
                                                    .Select(guiMod => guiMod.ToModule())
×
135
                                                    .OfType<CkanModule>())
136
                       .Select(other => allGuiMods[other.identifier])
×
137
                      ?? allGuiMods.Values;
138
            foreach (var otherMod in affectedMods)
×
139
            {
×
140
                otherMod.UpdateIsCached();
×
141
            }
×
142
        }
×
143

144
        [ForbidGUICalls]
145
        private void OnCacheChanged(NetModuleCache? prev)
146
        {
×
147
            if (prev != null)
×
148
            {
×
149
                prev.ModStored -= OnModStoredOrPurged;
×
150
                prev.ModPurged -= OnModStoredOrPurged;
×
151
            }
×
152
            if (Manager.Cache != null)
×
153
            {
×
154
                Manager.Cache.ModStored += OnModStoredOrPurged;
×
155
                Manager.Cache.ModPurged += OnModStoredOrPurged;
×
156
            }
×
157
            UpdateCachedByDownloads(null);
×
158
        }
×
159

160
        [ForbidGUICalls]
161
        private void OnModStoredOrPurged(CkanModule? module)
162
        {
×
163
            UpdateCachedByDownloads(module);
×
164
        }
×
165
    }
166
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc