mirror of
https://github.com/SoDOff-Project/sodoff.git
synced 2025-10-11 08:18:49 -07:00
async locking for VikingSession
This commit is contained in:
parent
bca383c4d0
commit
7dbcc456b9
@ -1,5 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using sodoff.Model;
|
using sodoff.Model;
|
||||||
|
|
||||||
namespace sodoff.Attributes;
|
namespace sodoff.Attributes;
|
||||||
@ -12,6 +13,9 @@ public class VikingSession : Attribute, IAsyncActionFilter {
|
|||||||
public Modes Mode { get; set; } = Modes.VIKING;
|
public Modes Mode { get; set; } = Modes.VIKING;
|
||||||
public bool UseLock = false;
|
public bool UseLock = false;
|
||||||
|
|
||||||
|
private static Dictionary<string, SemaphoreSlim> semaphores = new();
|
||||||
|
private static SemaphoreSlim dictSemaphore = new(1, 1);
|
||||||
|
|
||||||
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) {
|
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) {
|
||||||
DBContext ctx = context.HttpContext.RequestServices.GetService(typeof(DBContext)) as DBContext;
|
DBContext ctx = context.HttpContext.RequestServices.GetService(typeof(DBContext)) as DBContext;
|
||||||
|
|
||||||
@ -22,7 +26,7 @@ public class VikingSession : Attribute, IAsyncActionFilter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Session? session = ctx.Sessions.FirstOrDefault(x => x.ApiToken == Guid.Parse(context.HttpContext.Request.Form[ApiToken].ToString()));
|
Session? session = await ctx.Sessions.FirstOrDefaultAsync(x => x.ApiToken == Guid.Parse(context.HttpContext.Request.Form[ApiToken].ToString()));
|
||||||
|
|
||||||
// get viking / user id from session
|
// get viking / user id from session
|
||||||
|
|
||||||
@ -44,15 +48,16 @@ public class VikingSession : Attribute, IAsyncActionFilter {
|
|||||||
// NOTE: we can't refer to session.User / session.Viking here,
|
// NOTE: we can't refer to session.User / session.Viking here,
|
||||||
// because it may cause to ignore modifications from the threads we are waiting for
|
// because it may cause to ignore modifications from the threads we are waiting for
|
||||||
// we can use its only after vikingMutex.WaitOne()
|
// we can use its only after vikingMutex.WaitOne()
|
||||||
|
string semKey = "SoDOffViking:" + userVikingId;
|
||||||
Mutex vikingMutex = new Mutex(false, "SoDOffViking:" + userVikingId);
|
SemaphoreSlim semaphore = await GetSemaphore(semKey);
|
||||||
try {
|
try {
|
||||||
vikingMutex.WaitOne();
|
await semaphore.WaitAsync();
|
||||||
context.ActionArguments["user"] = session.User;
|
context.ActionArguments["user"] = session.User;
|
||||||
context.ActionArguments["viking"] = session.Viking;
|
context.ActionArguments["viking"] = session.Viking;
|
||||||
await next();
|
await next();
|
||||||
} finally {
|
} finally {
|
||||||
vikingMutex.ReleaseMutex();
|
semaphore.Release();
|
||||||
|
await RemoveSemaphore(semKey, semaphore);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
context.ActionArguments["user"] = session.User;
|
context.ActionArguments["user"] = session.User;
|
||||||
@ -60,4 +65,22 @@ public class VikingSession : Attribute, IAsyncActionFilter {
|
|||||||
await next();
|
await next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task<SemaphoreSlim> GetSemaphore(string key) {
|
||||||
|
await dictSemaphore.WaitAsync();
|
||||||
|
if (!semaphores.TryGetValue(key, out SemaphoreSlim semaphore)) {
|
||||||
|
semaphore = new SemaphoreSlim(1, 1);
|
||||||
|
semaphores.Add(key, semaphore);
|
||||||
|
}
|
||||||
|
dictSemaphore.Release();
|
||||||
|
return semaphore;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task RemoveSemaphore(string key, SemaphoreSlim sem) {
|
||||||
|
await dictSemaphore.WaitAsync();
|
||||||
|
if (sem.CurrentCount == 1) {
|
||||||
|
semaphores.Remove(key);
|
||||||
|
}
|
||||||
|
dictSemaphore.Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user