11using System . Text . Json ;
22
3+ using Microsoft . Extensions . Caching . Memory ;
4+
35using Refit ;
46
57using SkredvarselGarminWeb . LavinprognoserApi . Models ;
@@ -8,8 +10,11 @@ namespace SkredvarselGarminWeb.LavinprognoserApi;
810
911public partial class LavinprognoserApiClient (
1012 ILavinprognoserWfsApi wfsApi ,
11- ILavinprognoserWebsiteApi websiteApi ) : ILavinprognoserApi
13+ ILavinprognoserWebsiteApi websiteApi ,
14+ IMemoryCache memoryCache ) : ILavinprognoserApi
1215{
16+ private static readonly SemaphoreSlim FetchSemaphore = new ( 3 , 3 ) ;
17+
1318 public async Task < IEnumerable < WfsFeature < JsonElement > > > GetAllLocationPolygons ( )
1419 {
1520 var response = await GetAllWfsLocationPolygons ( "lavinprognoser:location" , null ) ;
@@ -43,25 +48,56 @@ private async Task<LavinprognoserDetailedWarning> ResolveWarningForDay(string sl
4348
4449 private async Task < LavinprognoserWebForecast ? > FetchForecastForDate ( string slug , DateOnly date )
4550 {
46- var response = await GetForecastPage ( slug , date ) ;
47- if ( ! response . IsSuccessStatusCode )
51+ var cacheKey = $ "LavinprognoserForecast_ { slug } _ { date : yyyy-MM-dd } " ;
52+ if ( memoryCache . TryGetValue < LavinprognoserWebForecast ? > ( cacheKey , out var cached ) )
4853 {
49- return default ;
54+ return cached ;
5055 }
5156
52- if ( response . Content ? . Content . Forecast != null )
57+ await FetchSemaphore . WaitAsync ( ) ;
58+ try
5359 {
54- return response . Content . Content . Forecast ;
60+ if ( memoryCache . TryGetValue < LavinprognoserWebForecast ? > ( cacheKey , out cached ) )
61+ {
62+ return cached ;
63+ }
64+
65+ var response = await GetForecastPage ( slug , date ) ;
66+ if ( ! response . IsSuccessStatusCode )
67+ {
68+ return default ;
69+ }
70+
71+ LavinprognoserWebForecast ? forecast ;
72+ if ( response . Content ? . Content . Forecast != null )
73+ {
74+ forecast = response . Content . Content . Forecast ;
75+ }
76+ else
77+ {
78+ var redirectedSlug = SwedishForecastAreaRegistry . TryGetSlugFromRequestUri ( response . RequestMessage ? . RequestUri ) ;
79+ if ( redirectedSlug == null || redirectedSlug == slug )
80+ {
81+ forecast = response . Content ? . Content . Forecast ;
82+ }
83+ else
84+ {
85+ var redirectedResponse = await GetForecastPage ( redirectedSlug , date ) ;
86+ forecast = redirectedResponse . Content ? . Content . Forecast ;
87+ }
88+ }
89+
90+ memoryCache . Set ( cacheKey , forecast , new MemoryCacheEntryOptions
91+ {
92+ AbsoluteExpirationRelativeToNow = TimeSpan . FromHours ( 1 )
93+ } ) ;
94+
95+ return forecast ;
5596 }
56-
57- var redirectedSlug = SwedishForecastAreaRegistry . TryGetSlugFromRequestUri ( response . RequestMessage ? . RequestUri ) ;
58- if ( redirectedSlug == null || redirectedSlug == slug )
97+ finally
5998 {
60- return response . Content ? . Content . Forecast ;
99+ FetchSemaphore . Release ( ) ;
61100 }
62-
63- var redirectedResponse = await GetForecastPage ( redirectedSlug , date ) ;
64- return redirectedResponse . Content ? . Content . Forecast ;
65101 }
66102
67103 private Task < ApiResponse < WfsFeatureCollection < JsonElement > > > GetAllWfsLocationPolygons ( string typeName , string ? cqlFilter ) =>
0 commit comments