fix: make default initialization concurrency-safe
This commit is contained in:
@@ -27,13 +27,7 @@ namespace JobTrackerApi.Controllers
|
||||
// Per-user rule settings when authenticated.
|
||||
if (!string.IsNullOrWhiteSpace(_db.CurrentUserId))
|
||||
{
|
||||
var u = await _db.UserRuleSettings.FirstOrDefaultAsync(x => x.OwnerUserId == _db.CurrentUserId, cancellationToken);
|
||||
if (u is null)
|
||||
{
|
||||
u = new UserRuleSettings { OwnerUserId = _db.CurrentUserId };
|
||||
_db.UserRuleSettings.Add(u);
|
||||
await _db.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
var u = await GetOrCreateUserSettingsAsync(_db.CurrentUserId, cancellationToken);
|
||||
|
||||
return Ok(new RuleSettings
|
||||
{
|
||||
@@ -64,12 +58,7 @@ namespace JobTrackerApi.Controllers
|
||||
// Per-user rule settings when authenticated.
|
||||
if (!string.IsNullOrWhiteSpace(_db.CurrentUserId))
|
||||
{
|
||||
var s = await _db.UserRuleSettings.FirstOrDefaultAsync(x => x.OwnerUserId == _db.CurrentUserId, cancellationToken);
|
||||
if (s is null)
|
||||
{
|
||||
s = new UserRuleSettings { OwnerUserId = _db.CurrentUserId };
|
||||
_db.UserRuleSettings.Add(s);
|
||||
}
|
||||
var s = await GetOrCreateUserSettingsAsync(_db.CurrentUserId, cancellationToken);
|
||||
|
||||
s.AppliedFollowUpDays = Clamp(incoming.AppliedFollowUpDays, 1, 365);
|
||||
s.AppliedGhostDays = Clamp(incoming.AppliedGhostDays, 1, 365);
|
||||
@@ -101,6 +90,27 @@ namespace JobTrackerApi.Controllers
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
private async Task<UserRuleSettings> GetOrCreateUserSettingsAsync(string ownerUserId, CancellationToken cancellationToken)
|
||||
{
|
||||
var settings = await _db.UserRuleSettings.FirstOrDefaultAsync(x => x.OwnerUserId == ownerUserId, cancellationToken);
|
||||
if (settings is not null) return settings;
|
||||
|
||||
settings = new UserRuleSettings { OwnerUserId = ownerUserId };
|
||||
_db.UserRuleSettings.Add(settings);
|
||||
try
|
||||
{
|
||||
await _db.SaveChangesAsync(cancellationToken);
|
||||
return settings;
|
||||
}
|
||||
catch (DbUpdateException)
|
||||
{
|
||||
_db.Entry(settings).State = EntityState.Detached;
|
||||
settings = await _db.UserRuleSettings.FirstOrDefaultAsync(x => x.OwnerUserId == ownerUserId, cancellationToken);
|
||||
if (settings is null) throw;
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
||||
private static int Clamp(int v, int min, int max) => v < min ? min : v > max ? max : v;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user