diff --git a/Directory.Packages.props b/Directory.Packages.props index 0cd8288..00c5a71 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -31,6 +31,7 @@ + diff --git a/src/HelloShop.BasketService/HelloShop.BasketService.csproj b/src/HelloShop.BasketService/HelloShop.BasketService.csproj index 2b317ee..1dcee1a 100644 --- a/src/HelloShop.BasketService/HelloShop.BasketService.csproj +++ b/src/HelloShop.BasketService/HelloShop.BasketService.csproj @@ -17,6 +17,7 @@ + diff --git a/src/HelloShop.BasketService/Program.cs b/src/HelloShop.BasketService/Program.cs index 966bc47..203cddf 100644 --- a/src/HelloShop.BasketService/Program.cs +++ b/src/HelloShop.BasketService/Program.cs @@ -28,7 +28,8 @@ builder.Services.AddAuthentication().AddJwtBearer(options => builder.Services.AddHttpContextAccessor(); builder.AddRedisDistributedCache("cache"); -builder.Services.AddSingleton(); +builder.Services.AddHybridCache(); +builder.Services.AddSingleton(); builder.Services.AddGrpc().AddJsonTranscoding(); builder.Services.AddGrpcSwagger(); diff --git a/src/HelloShop.BasketService/Repositories/BasketRepository.cs b/src/HelloShop.BasketService/Repositories/BasketRepository.cs new file mode 100644 index 0000000..52480d4 --- /dev/null +++ b/src/HelloShop.BasketService/Repositories/BasketRepository.cs @@ -0,0 +1,37 @@ +// Copyright (c) HelloShop Corporation. All rights reserved. +// See the license file in the project root for more information. + +using HelloShop.BasketService.Entities; +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Caching.Hybrid; +using System.Threading; + +namespace HelloShop.BasketService.Repositories +{ + public class BasketRepository(HybridCache cache) : IBasketRepository + { + private const string BasketKeyPrefix = "basket"; + + private static string GetBasketKey(int customerId) => $"{BasketKeyPrefix}:{customerId}"; + + public async Task DeleteBasketAsync(int customerId, CancellationToken cancellationToken = default) => await cache.RemoveAsync(GetBasketKey(customerId), cancellationToken); + + public async Task GetBasketAsync(int customerId, CancellationToken cancellationToken = default) + { + return await cache.GetOrCreateAsync(GetBasketKey(customerId), async cancel => await Task.FromResult(default), cancellationToken: cancellationToken); + } + + public async Task UpdateBasketAsync(CustomerBasket basket, CancellationToken cancellationToken = default) + { + HybridCacheEntryOptions options = new() + { + Expiration = TimeSpan.MaxValue, + LocalCacheExpiration = TimeSpan.FromMinutes(5), + }; + + await cache.SetAsync(GetBasketKey(basket.BuyerId), basket, options, cancellationToken: cancellationToken); + + return await GetBasketAsync(basket.BuyerId, cancellationToken); + } + } +} diff --git a/src/HelloShop.BasketService/Repositories/DistributedCacheBasketRepository.cs b/src/HelloShop.BasketService/Repositories/DistributedCacheBasketRepository.cs deleted file mode 100644 index 135609f..0000000 --- a/src/HelloShop.BasketService/Repositories/DistributedCacheBasketRepository.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) HelloShop Corporation. All rights reserved. -// See the license file in the project root for more information. - -using HelloShop.BasketService.Entities; -using Microsoft.Extensions.Caching.Distributed; - -namespace HelloShop.BasketService.Repositories -{ - public class DistributedCacheBasketRepository(IDistributedCache cache) : IBasketRepository - { - private const string BasketKeyPrefix = "basket"; - - private static string GetBasketKey(int customerId) => $"{BasketKeyPrefix}:{customerId}"; - - public async Task DeleteBasketAsync(int customerId, CancellationToken token = default) => await cache.RemoveAsync(GetBasketKey(customerId), token); - - public async Task GetBasketAsync(int customerId, CancellationToken token = default) => await cache.GetObjectAsync(GetBasketKey(customerId), token); - - public async Task UpdateBasketAsync(CustomerBasket basket, CancellationToken token = default) - { - DistributedCacheEntryOptions options = new() { SlidingExpiration = TimeSpan.MaxValue }; - - await cache.SetObjectAsync(GetBasketKey(basket.BuyerId), basket, options, token); - - return await GetBasketAsync(basket.BuyerId, token); - } - } -} diff --git a/src/HelloShop.BasketService/Repositories/IBasketRepository.cs b/src/HelloShop.BasketService/Repositories/IBasketRepository.cs index 835a026..00694f9 100644 --- a/src/HelloShop.BasketService/Repositories/IBasketRepository.cs +++ b/src/HelloShop.BasketService/Repositories/IBasketRepository.cs @@ -7,10 +7,10 @@ namespace HelloShop.BasketService.Repositories { public interface IBasketRepository { - Task GetBasketAsync(int customerId, CancellationToken token = default); + Task GetBasketAsync(int customerId, CancellationToken cancellationToken = default); - Task UpdateBasketAsync(CustomerBasket basket, CancellationToken token = default); + Task UpdateBasketAsync(CustomerBasket basket, CancellationToken cancellationToken = default); - Task DeleteBasketAsync(int customerId, CancellationToken token = default); + Task DeleteBasketAsync(int customerId, CancellationToken cancellationToken = default); } }