Skip to content

Commit ba74b54

Browse files
committed
Implemented redlock for createPaymentIntent
1 parent 591ae42 commit ba74b54

File tree

7 files changed

+90
-2
lines changed

7 files changed

+90
-2
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using dotnet_qrshop.Common.Models;
2+
using RedLockNet;
3+
using RedLockNet.SERedis;
4+
using StackExchange.Redis;
5+
6+
namespace dotnet_qrshop.Common.Extensions;
7+
8+
public static class DependencyInjectionExtensions
9+
{
10+
public static void AddRedisServices(this WebApplicationBuilder builder)
11+
{
12+
var configurationOptions = ConfigurationOptions.Parse(builder.Configuration.GetConnectionString("Redis") ?? "localhost:6379", true);
13+
configurationOptions.AbortOnConnectFail = false;
14+
configurationOptions.ConnectRetry = 3;
15+
16+
builder.Services.AddSingleton<IConnectionMultiplexer>(sp => ConnectionMultiplexer.Connect(configurationOptions));
17+
18+
builder.Services.Configure<RedlockSettings>(builder.Configuration.GetSection("Redlock"));
19+
builder.Services.AddSingleton<IDistributedLockFactory, RedLockFactory>(_ =>
20+
RedLockFactory.Create([ConnectionMultiplexer.Connect(configurationOptions)]));
21+
}
22+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace dotnet_qrshop.Common.Models;
2+
3+
public class RedlockSettings
4+
{
5+
public TimeSpan Expiry { get; set; }
6+
public TimeSpan Wait { get; set; }
7+
public TimeSpan Retry { get; set; }
8+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Carter;
2+
using dotnet_qrshop.Common.Models;
3+
using Microsoft.Extensions.Options;
4+
using RedLockNet;
5+
6+
namespace dotnet_qrshop.Features.Payments.Commands.CancelPaymentIntent;
7+
8+
public class CancelPaymentIntentEndpoint(
9+
IDistributedLockFactory _lockFactory,
10+
IOptions<RedlockSettings> redlockOptions) : ICarterModule
11+
{
12+
private readonly RedlockSettings _lockSettings = redlockOptions.Value;
13+
public void AddRoutes(IEndpointRouteBuilder app)
14+
{
15+
app.MapGet("testredis", async () =>
16+
{
17+
using var redlock = await _lockFactory.CreateLockAsync("test", _lockSettings.Expiry, _lockSettings.Wait, _lockSettings.Retry);
18+
if (redlock.IsAcquired)
19+
{
20+
Console.WriteLine("Acquired Lock - test Dylan");
21+
await Task.Delay(10000);
22+
}
23+
else
24+
{
25+
Console.WriteLine("Didn't acquire lock");
26+
}
27+
});
28+
}
29+
}

src/Features/Payments/Commands/CreatePaymentIntent/CreatePaymentIntentCommandHandler.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,32 @@
22
using dotnet_qrshop.Abstractions.Authentication;
33
using dotnet_qrshop.Abstractions.Messaging;
44
using dotnet_qrshop.Common.Enums;
5+
using dotnet_qrshop.Common.Models;
56
using dotnet_qrshop.Common.Results;
67
using dotnet_qrshop.Infrastructure.Database.DbContext;
78
using Microsoft.EntityFrameworkCore;
9+
using Microsoft.Extensions.Options;
10+
using RedLockNet;
811

912
namespace dotnet_qrshop.Features.Payments.Commands.CreatePaymentIntent;
1013

1114
public class CreatePaymentIntentCommandHandler(
1215
ApplicationDbContext _dbContext,
1316
IUserContext _userContext,
14-
IPaymentService _paymentService) : ICommandHandler<CreatePaymentIntentCommand, string>
17+
IPaymentService _paymentService,
18+
IDistributedLockFactory _lockFactory,
19+
IOptions<RedlockSettings> redlockOptions) : ICommandHandler<CreatePaymentIntentCommand, string>
1520
{
21+
private readonly RedlockSettings _lockSettings = redlockOptions.Value;
1622
public async Task<Result<string>> Handle(CreatePaymentIntentCommand command, CancellationToken cancellationToken)
1723
{
24+
using var redlock = await _lockFactory.CreateLockAsync("test", _lockSettings.Expiry, _lockSettings.Wait, _lockSettings.Retry);
25+
if (!redlock.IsAcquired)
26+
{
27+
// TODO DYLAN: LOG here
28+
return Result.Failure<string>(Error.Conflict("Couldn't create payment intent", "Error processing payment, please try again or contact the support"));
29+
}
30+
1831
var orderInfo = await _dbContext.Orders
1932
.AsNoTracking()
2033
.Where(o => o.UserId == _userContext.UserId && o.Id == command.OrderId)

src/Program.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using dotnet_qrshop.Abstractions.Authentication;
44
using dotnet_qrshop.Abstractions.Messaging;
55
using dotnet_qrshop.Common.Behaviours;
6+
using dotnet_qrshop.Common.Extensions;
67
using dotnet_qrshop.Common.Models.Identity;
78
using dotnet_qrshop.Domains;
89
using dotnet_qrshop.Features.Identity;
@@ -77,6 +78,9 @@
7778
// Authorization
7879
builder.Services.AddAuthorization();
7980

81+
// Redis && Redlock
82+
builder.AddRedisServices();
83+
8084
// Stripe
8185
StripeConfiguration.ApiKey = builder.Configuration["StripeApiKey"];
8286

@@ -135,4 +139,6 @@
135139

136140
app.MapCarter();
137141

138-
app.Run();
142+
app.Run();
143+
144+

src/appsettings.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55
"Microsoft.AspNetCore": "Warning"
66
}
77
},
8+
"Redis": {
9+
"ConnectionString": ""
10+
},
11+
"Redlock": {
12+
"Expiry": "00:00:30",
13+
"Wait": "00:00:02",
14+
"Retry": "00:00:00.500"
15+
},
816
"AllowedHosts": "*",
917
"ConnectionStrings": {
1018
"Database": "..."

src/dotnet-qrshop.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@
8383
<PrivateAssets>all</PrivateAssets>
8484
</PackageReference>
8585
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
86+
<PackageReference Include="RedLock.net" Version="2.3.2" />
8687
<PackageReference Include="Scrutor" Version="6.0.1" />
88+
<PackageReference Include="StackExchange.Redis" Version="2.9.32" />
8789
<PackageReference Include="Stripe.net" Version="49.0.0" />
8890
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.1" />
8991
<PackageReference Include="System.Collections" Version="4.3.0" />

0 commit comments

Comments
 (0)