Skip to content

Commit 5f0811e

Browse files
feat: using database lock to protect bot api token
Preventing multiple threads from updating the bot's oauth token using a database level lock. It's a bit of a hack since ef core doesn't support pessmistic locking out-of-the-box. This work around works between the running application and dbeaver.
1 parent e023a78 commit 5f0811e

File tree

5 files changed

+456
-1
lines changed

5 files changed

+456
-1
lines changed

src/Nullinside.Api.Model/Ddl/User.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System.ComponentModel.DataAnnotations;
2+
13
using Microsoft.EntityFrameworkCore;
24

35
namespace Nullinside.Api.Model.Ddl;
@@ -60,6 +62,7 @@ public class User : ITableModel {
6062
/// <summary>
6163
/// The last timestamp of when the user logged into the site.
6264
/// </summary>
65+
[Timestamp]
6366
public DateTime UpdatedOn { get; set; }
6467

6568
/// <summary>
@@ -92,6 +95,8 @@ public void OnModelCreating(ModelBuilder modelBuilder) {
9295
.HasMaxLength(255);
9396
entity.Property(e => e.Token)
9497
.HasMaxLength(255);
98+
entity.Property(e => e.UpdatedOn)
99+
.IsRowVersion();
95100
// TODO: Add the other strings in this file with lengths
96101
});
97102
}

src/Nullinside.Api.Model/Migrations/20250228164901_UserTableTimestamp.Designer.cs

Lines changed: 314 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System;
2+
using Microsoft.EntityFrameworkCore.Migrations;
3+
using MySql.EntityFrameworkCore.Metadata;
4+
5+
#nullable disable
6+
7+
namespace Nullinside.Api.Model.Migrations
8+
{
9+
/// <inheritdoc />
10+
public partial class UserTableTimestamp : Migration
11+
{
12+
/// <inheritdoc />
13+
protected override void Up(MigrationBuilder migrationBuilder)
14+
{
15+
migrationBuilder.AlterColumn<DateTime>(
16+
name: "UpdatedOn",
17+
table: "Users",
18+
type: "datetime(6)",
19+
rowVersion: true,
20+
nullable: false,
21+
oldClrType: typeof(DateTime),
22+
oldType: "datetime(6)")
23+
.Annotation("MySQL:ValueGenerationStrategy", MySQLValueGenerationStrategy.ComputedColumn);
24+
}
25+
26+
/// <inheritdoc />
27+
protected override void Down(MigrationBuilder migrationBuilder)
28+
{
29+
migrationBuilder.AlterColumn<DateTime>(
30+
name: "UpdatedOn",
31+
table: "Users",
32+
type: "datetime(6)",
33+
nullable: false,
34+
oldClrType: typeof(DateTime),
35+
oldType: "datetime(6)",
36+
oldRowVersion: true)
37+
.OldAnnotation("MySQL:ValueGenerationStrategy", MySQLValueGenerationStrategy.ComputedColumn);
38+
}
39+
}
40+
}

src/Nullinside.Api.Model/Migrations/NullinsideContextModelSnapshot.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ protected override void BuildModel(ModelBuilder modelBuilder)
1616
{
1717
#pragma warning disable 612, 618
1818
modelBuilder
19-
.HasAnnotation("ProductVersion", "8.0.8")
19+
.HasAnnotation("ProductVersion", "8.0.11")
2020
.HasAnnotation("Relational:MaxIdentifierLength", 64);
2121

2222
modelBuilder.Entity("Nullinside.Api.Model.Ddl.DockerDeployments", b =>
@@ -247,6 +247,8 @@ protected override void BuildModel(ModelBuilder modelBuilder)
247247
.HasColumnType("longtext");
248248

249249
b.Property<DateTime>("UpdatedOn")
250+
.IsConcurrencyToken()
251+
.ValueGeneratedOnAddOrUpdate()
250252
.HasColumnType("datetime(6)");
251253

252254
b.HasKey("Id");

0 commit comments

Comments
 (0)