Skip to content

Commit

Permalink
Moved locking class to its own package.
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkCiliaVincenti committed Nov 22, 2021
1 parent b9f4740 commit ba39d0e
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 103 deletions.
36 changes: 21 additions & 15 deletions OpenWeatherMap.Cache/Enums/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,37 @@
public class Enums
{
/// <summary>
/// Enumeration for OpenWeatherMap.Cache
/// If the time elapsed since the last fetch for the given location exceeds the cache period (i.e. a new API call is required)
/// but is within the resiliency period (i.e. the previous readings are still available in the cache), the API reported measured
/// time in the cache value is sometimes more recent than the latest value fetched from the API. There are three modes to tackle
/// this issue.
/// </summary>
public enum FetchMode
{
/// <summary>
/// If the time elapsed since the last fetch for the given location exceeds the cache period but is
/// within the resiliency period (i.e. still available in the cache), and the API reported measured
/// time in the cache value is more recent than the latest value fetched from the API, then return
/// the more recent cached result.<br></br><br></br>IMPORTANT: Frequent calls may impact your API
/// usage.
/// If the time elapsed since the last fetch for the given location exceeds the cache period (i.e.
/// a new API call is required) but is within the resiliency period (i.e. the previous readings are
/// still available in the cache), and the API reported measured time in the cache value is more
/// recent than the latest value fetched from the API, then return the more recent cached result. The
/// implication is that if you immediately request another reading it will also hit the API again.
/// <br></br><br></br>IMPORTANT: Frequent calls may impact your API usage.
/// </summary>
AlwaysUseLastMeasured,
/// <summary>
/// If the time elapsed since the last fetch for the given location exceeds the cache period but is
/// within the resiliency period (i.e. still available in the cache), and the API reported measured
/// time in the cache value is more recent than the latest value fetched from the API, then return
/// the more recent cached result.<br></br><br></br>In order to protect impact on your API usage,
/// this setting updates the cache value's fetched date and extends the cache lifetime.
/// If the time elapsed since the last fetch for the given location exceeds the cache period (i.e.
/// a new API call is required) but is within the resiliency period (i.e. the previous readings are
/// still available in the cache), and the API reported measured time in the cache value is more
/// recent than the latest value fetched from the API, then return the more recent cached result.
/// <br></br><br></br>In order to protect impact on your API usage, this setting updates the cache
/// value's fetched date and extends the cache lifetime.
/// </summary>
AlwaysUseLastMeasuredButExtendCache,
/// <summary>
/// If the time elapsed since the last fetch for the given location exceeds the cache period but is
/// within the resiliency period (i.e. still available in the cache), and the API reported measured
/// time in the cache value is more recent than the latest value fetched from the API, then return
/// and cache the last fetched API result, even though it is being reported to be older by the API.
/// If the time elapsed since the last fetch for the given location exceeds the cache period (i.e.
/// a new API call is required) but is within the resiliency period (i.e. the previous readings are
/// still available in the cache), and the API reported measured time in the cache value is more
/// recent than the latest value fetched from the API, then return and cache the last fetched API
/// result, even though it is being reported to be older by the API.
/// </summary>
AlwaysUseLastFetchedValue
}
Expand Down
73 changes: 0 additions & 73 deletions OpenWeatherMap.Cache/Helpers/AsyncDuplicateLock.cs

This file was deleted.

11 changes: 6 additions & 5 deletions OpenWeatherMap.Cache/OpenWeatherMap.Cache.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@
<RepositoryUrl>https://github.com/MarkCiliaVincenti/OpenWeatherMap.Cache.git</RepositoryUrl>
<PackageProjectUrl>https://github.com/MarkCiliaVincenti/OpenWeatherMap.Cache</PackageProjectUrl>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<Version>1.4.4</Version>
<Version>1.4.5</Version>
<PackageIcon>logo.png</PackageIcon>
<PackageReleaseNotes>Bumping UnitsNet package version.</PackageReleaseNotes>
<Description>An asynchronous .NET Standard 2.0 library that allows you to fetch &amp; cache current weather readings from the OpenWeatherMap API, with in-built resiliency that can extend the cache lifetime in case the API is unreachable.</Description>
<PackageReleaseNotes>Moved locking class to its own package.</PackageReleaseNotes>
<Description>An asynchronous .NET Standard 2.0 library that allows you to fetch &amp; cache current weather readings from the OpenWeather API, with built0-in resiliency that can extend the cache lifetime in case the API is unreachable.</Description>
<Copyright>© 2021 Mark Cilia Vincenti</Copyright>
<PackageTags>OpenWeather,OpenWeatherMap,cache,weather,API,.NET Standard,netstandard</PackageTags>
<RepositoryType>git</RepositoryType>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<AssemblyVersion>1.4.4.0</AssemblyVersion>
<FileVersion>1.4.4.0</FileVersion>
<AssemblyVersion>1.4.5.0</AssemblyVersion>
<FileVersion>1.4.5.0</FileVersion>
<PackageReadmeFile>README.md</PackageReadmeFile>
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
<EnableNETAnalyzers>True</EnableNETAnalyzers>
Expand All @@ -28,6 +28,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AsyncKeyedLock" Version="1.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
<PackageReference Include="System.Text.Json" Version="6.0.0" />
Expand Down
6 changes: 3 additions & 3 deletions OpenWeatherMap.Cache/OpenWeatherMapCache.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Microsoft.Extensions.Caching.Memory;
using AsyncKeyedLock;
using Microsoft.Extensions.Caching.Memory;
using OpenWeatherMap.Cache.Constants;
using OpenWeatherMap.Cache.Helpers;
using OpenWeatherMap.Cache.Models;
using System;
using System.IO;
Expand Down Expand Up @@ -190,7 +190,7 @@ private async Task<ApiWeatherResult> GetApiWeatherResultFromLocationQuery<T>(T l
/// <returns>A <see cref="Readings"/> object for the provided location, or the default value if the operation failed (<see cref="Readings.IsSuccessful"/> = false).</returns>
public async Task<Readings> GetReadingsAsync<T>(T locationQuery) where T : ILocationQuery
{
var lockObj = await AsyncDuplicateLock.LockAsync(locationQuery);
var lockObj = await AsyncKeyedLocker.LockAsync(locationQuery);

var dateTime = DateTime.UtcNow;
var found = _memoryCache.TryGetValue(locationQuery, out Readings apiCache);
Expand Down
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
# OpenWeatherMap.Cache
An asynchronous .NET Standard library that allows you to fetch & cache current weather readings from the [OpenWeatherMap](https://openweathermap.org/) API, with in-built resiliency that can extend the cache lifetime in case the API is unreachable.
An asynchronous .NET Standard 2.0 library that allows you to fetch & cache current weather readings from the [OpenWeather](https://openweathermap.org/) API, with built-in resiliency that can extend the cache lifetime in case the API is unreachable.

Supports .NET Framework 4.6.1 or later, .NET Core 2.0 or later, and .NET 5.0 or later.

## Installation
The recommended means is to use [NuGet](https://www.nuget.org/packages/OpenWeatherMap.Cache), but you could also download the source code from [here](https://github.com/MarkCiliaVincenti/OpenWeatherMap.Cache/releases).

## Choose the fetch mode
If the time elapsed since the last fetch for the given location exceeds the cache period but is within the resiliency period (i.e. still available in the cache), the API reported measured time in the cache value is sometimes more recent than the latest value fetched from the API.
If the time elapsed since the last fetch for the given location exceeds the cache period (i.e. a new API call is required) but is within the resiliency period (i.e. the previous readings are still available in the cache), the API reported measured time in the cache value is sometimes more recent than the latest value fetched from the API. There are three modes to tackle this issue:

With *FetchMode.AlwaysUseLastMeasured*, the value still available in the cache is returned. **IMPORTANT:** Frequent calls may impact your API usage.
With *FetchMode.AlwaysUseLastMeasured*, the value still available in the cache is returned. The implication is that if you immediately request another reading it will also hit the API again. **IMPORTANT:** Frequent calls may impact your API usage.

With *FetchMode.AlwaysUseLastMeasuredButExtendCache* (default), the value still available in the cache is returned but in order to protect impact on your API usage, this setting updates the cache value's fetched date and extends the cache lifetime.
With *FetchMode.AlwaysUseLastMeasuredButExtendCache* (default, recommended), the value still available in the cache is returned but in order to protect impact on your API usage, this setting updates the cache value's fetched date and extends the cache lifetime.

With *FetchMode.AlwaysUseLastFetchedValue*, the last fetched API result is returned anyway, even though it is being reported to be older by the API.
With *FetchMode.AlwaysUseLastFetchedValue*, the last fetched API result is returned anyway, even though it is being reported to be older by the API.

## Initialization with Dependency Injection
In your Startup.cs (ConfigureServices):
Expand Down Expand Up @@ -42,7 +44,7 @@ else
}
```

or by zip code and country code:
or by zip code (post code) and country code:
```csharp
var locationQuery = new OpenWeatherMap.Cache.Models.ZipCode("94040", "us");
var readings = await openWeatherMapCache.GetReadingsAsync(locationQuery);
Expand Down Expand Up @@ -72,7 +74,7 @@ else
}
```

or by zip code and country code:
or by zip code (post code) and country code:
```csharp
var locationQuery = new OpenWeatherMap.Cache.Models.ZipCode("94040", "us");
var readings = openWeatherMapCache.GetReadingsAsync(locationQuery).Result;
Expand Down

0 comments on commit ba39d0e

Please sign in to comment.