66using System . Linq ;
77using System . Net ;
88using System . Threading ;
9- using System . Threading . Tasks ;
109using ZkData ;
1110
1211namespace ZeroKWeb
@@ -15,9 +14,10 @@ public static class ResourceLinkProvider
1514 {
1615 const double SpringfilesRecheckHours = 24 ;
1716
18- // dedup concurrent springfiles probes per Md5 — Lazy guarantees a single Task even under contention
19- static readonly ConcurrentDictionary < string , Lazy < Task < bool > > > InflightProbes
20- = new ConcurrentDictionary < string , Lazy < Task < bool > > > ( ) ;
17+ // dedup concurrent springfiles probes per Md5 — Lazy<bool> with ExecutionAndPublication
18+ // ensures the factory (the actual probe) runs exactly once; concurrent callers block on .Value
19+ static readonly ConcurrentDictionary < string , Lazy < bool > > InflightProbes
20+ = new ConcurrentDictionary < string , Lazy < bool > > ( ) ;
2121
2222 public static bool GetLinksAndTorrent ( string internalName ,
2323 out List < string > links ,
@@ -89,16 +89,15 @@ static bool IsSpringfilesAvailable(ResourceContentFile content, string url)
8989 return content . LinkCount > 0 ;
9090
9191 var md5 = content . Md5 ;
92- var length = content . Length ;
9392 return InflightProbes . GetOrAdd ( md5 , key => new Lazy < Task < bool > > (
94- ( ) => Task . Run ( ( ) => RunProbe ( key , url , length ) ) ,
93+ ( ) => Task . Run ( ( ) => RunProbe ( key ) ) ,
9594 LazyThreadSafetyMode . ExecutionAndPublication ) ) . Value . Result ;
9695 }
9796
9897 // The cache re-check inside the using block covers the gap between Task completion
9998 // and InflightProbes eviction — a caller arriving in that window creates a new Lazy
10099 // but the new probe sees the just-persisted LastLinkCheck and skips the HEAD.
101- static bool RunProbe ( string md5 , string url , int length )
100+ static bool RunProbe ( string md5 )
102101 {
103102 try
104103 {
0 commit comments