diff --git a/source/dub/packagesuppliers/fallback.d b/source/dub/packagesuppliers/fallback.d index 0fabba3..39a61e6 100644 --- a/source/dub/packagesuppliers/fallback.d +++ b/source/dub/packagesuppliers/fallback.d @@ -5,19 +5,26 @@ package abstract class AbstractFallbackPackageSupplier : PackageSupplier { - protected PackageSupplier[] m_suppliers; + protected import core.time : minutes; + protected import std.datetime : Clock, SysTime; + + static struct Pair { PackageSupplier ps; SysTime failTime; } + protected Pair[] m_suppliers; this(PackageSupplier[] suppliers) { assert(suppliers.length); - m_suppliers = suppliers; + m_suppliers.length = suppliers.length; + foreach (i, ps; suppliers) + m_suppliers[i].ps = ps; } override @property string description() { import std.algorithm.iteration : map; import std.format : format; - return format("%s (fallbacks %-(%s, %))", m_suppliers[0].description, m_suppliers[1 .. $].map!(x => x.description)); + return format("%s (fallbacks %-(%s, %))", m_suppliers[0].ps.description, + m_suppliers[1 .. $].map!(pair => pair.ps.description)); } // Workaround https://issues.dlang.org/show_bug.cgi?id=2525 @@ -43,27 +50,29 @@ Exception firstEx; try - return m_suppliers[0].%1$s(args); + return m_suppliers[0].ps.%1$s(args); catch (Exception e) { logDiagnostic("Package supplier %%s failed with '%%s', trying fallbacks.", - m_suppliers[0].description, e.msg); - m_suppliers = m_suppliers[1 .. $]; + m_suppliers[0].ps.description, e.msg); firstEx = e; } - foreach (fallback; m_suppliers) + immutable now = Clock.currTime; + foreach (ref pair; m_suppliers[1 .. $]) { + if (pair.failTime > now - 10.minutes) + continue; try { - scope (success) logDiagnostic("Fallback %%s succeeded", fallback.description); - return fallback.%1$s(args); + scope (success) logDiagnostic("Fallback %%s succeeded", pair.ps.description); + return pair.ps.%1$s(args); } - catch(Exception e) + catch (Exception e) { + pair.failTime = now; logDiagnostic("Fallback package supplier %%s failed with '%%s'.", - fallback.description, e.msg); - m_suppliers = m_suppliers[1 .. $]; + pair.ps.description, e.msg); } } throw firstEx;