Scenario:
I have a microservice that provides IP address information for other part of the system to use. This microservice uses an external API to get this info and each response will be saved on local DB to be reused for some time (say one month).
So, for each request this service first checks the local DB and if no row is available for that IP address, then it makes an API request, saves the response and then returns the information.
The external API has limited quota per month, so if two or more threads send request for the same IP address, it is a waste of quota.
In such cases how can I let only one thread to make the external API call and other threads to wait for the result?
This is my singleton service:
// Registered as Singleton in ASP.NET Core DI
public class IPInfoService(
IServiceProvider serviceProvider,
IConfiguration configuration)
{
private readonly string ApiKey = configuration["MyApiKey"] ?? "";
private readonly HttpClient _httpClient = new();
public async Task<IPInfoDTO> GetIPInfoAsync(string ipString)
{
using var scope = serviceProvider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<IpInfoDbContext>();
var dbRow = // fetch from DB
if (dbRow is { })
{
// Return the result
// It's OK if multiple threads do this
}
// We need to call external API
// It's not OK if multiple threads call external API for the same `ipString`
var ipInfo = // fetch from API
// Save to DB
// Return the result
}
}