@@ -11,6 +11,8 @@ public partial class ModDbService(
1111 ModDbGetCdnLinkService modDbGetCdnLinkServiceSvc
1212)
1313{
14+ private static readonly SemaphoreSlim _lock = new ( 1 ) ;
15+
1416 public async Task DownloadAddonAsync (
1517 string url ,
1618 string output ,
@@ -49,29 +51,40 @@ public async Task DownloadAddonAsync(
4951 await outerRetry . ExecuteAsync (
5052 async ct =>
5153 {
52- var diabolicalResilience = BuildRetry ( ) ;
53- await diabolicalResilience . ExecuteAsync (
54- async innertCt =>
55- diabolicalLink = await GetCdnLinkAsync (
56- url ,
57- visitedMirrors ,
58- useCurl ,
59- invalidateCache ,
60- ct : innertCt
61- ) ,
62- ct
63- ) ;
54+ DirectoryInfo ? parentPath ;
6455
65- // if bad mirror
66- if ( string . IsNullOrWhiteSpace ( diabolicalLink ) )
56+ try
6757 {
68- throw new ModDbUtilityException ( "Failed to get diabolical link" ) ;
69- }
58+ await _lock . WaitAsync ( ct ) ;
59+
60+ var diabolicalResilience = BuildRetry ( ) ;
61+ await diabolicalResilience . ExecuteAsync (
62+ async innertCt =>
63+ diabolicalLink = await GetCdnLinkAsync (
64+ url ,
65+ visitedMirrors ,
66+ useCurl ,
67+ invalidateCache ,
68+ ct : innertCt
69+ ) ,
70+ ct
71+ ) ;
72+
73+ // if bad mirror
74+ if ( string . IsNullOrWhiteSpace ( diabolicalLink ) )
75+ {
76+ throw new ModDbUtilityException ( "Failed to get diabolical link" ) ;
77+ }
7078
71- var parentPath = Directory . GetParent ( output ) ;
72- if ( parentPath is not null && ! parentPath . Exists )
79+ parentPath = Directory . GetParent ( output ) ;
80+ if ( parentPath is not null && ! parentPath . Exists )
81+ {
82+ parentPath . Create ( ) ;
83+ }
84+ }
85+ finally
7386 {
74- parentPath . Create ( ) ;
87+ _lock . Release ( ) ;
7588 }
7689
7790 await curlService . DownloadFileAsync (
@@ -100,10 +113,7 @@ private static ResiliencePipeline BuildRetry()
100113 not null => ValueTask . FromResult ( true ) ,
101114 _ => ValueTask . FromResult ( false ) ,
102115 } ,
103- OnRetry = args =>
104- {
105- return ValueTask . CompletedTask ;
106- } ,
116+ OnRetry = args => ValueTask . CompletedTask ,
107117 }
108118 )
109119 . Build ( ) ;
@@ -124,7 +134,11 @@ private static ResiliencePipeline BuildRetry()
124134 invalidateCache : invalidateCache ,
125135 cancellationToken : ct
126136 ) ;
127- var getContentTask = curlService . GetStringAsync ( url , useCurl : useCurl , cancellationToken : ct ) ;
137+ var getContentTask = curlService . GetStringAsync (
138+ url ,
139+ useCurl : useCurl ,
140+ cancellationToken : ct
141+ ) ;
128142 var results = await Task . WhenAll ( mirrorTask , getContentTask ) ;
129143
130144 var ( mirror , content ) = ( results [ 0 ] , results [ 1 ] ) ;
0 commit comments