Added more controls to UI

Fixed issue with queue infinite looping if next user in queue was revoked
This commit is contained in:
henry 2025-05-14 02:03:27 -04:00
parent 261490ec74
commit a96a3c3a82
6 changed files with 68 additions and 11 deletions

View File

@ -7,8 +7,11 @@
<PageTitle>AccessQueue Playground</PageTitle> <PageTitle>AccessQueue Playground</PageTitle>
<p>
<Button Color="ButtonColor.Success" @onclick="AddUser">Add User</Button> <Button Color="ButtonColor.Success" @onclick="AddUser">Add User</Button>
<Button Color="ButtonColor.Danger" @onclick="RevokeAllAccess">Revoke All</Button>
<Button Color="ButtonColor.Warning" @onclick="Reset">Reset Data</Button>
</p>
@if (Status != null) @if (Status != null)
{ {
<h2>Users with access</h2> <h2>Users with access</h2>
@ -25,6 +28,11 @@
<Switch Value="context.Active" ValueExpression="() => context.Active" ValueChanged="(value) => SetUserActive(context.Id, value)" /> <Switch Value="context.Active" ValueExpression="() => context.Active" ValueChanged="(value) => SetUserActive(context.Id, value)" />
</ChildContent> </ChildContent>
</GridColumn> </GridColumn>
<GridColumn TItem="User" HeaderText="Revoke">
<ChildContent>
<Button Color="ButtonColor.Danger" @onclick="() => RevokeAccess(context.Id)">Revoke Access</Button>
</ChildContent>
</GridColumn>
</GridColumns> </GridColumns>
</Grid> </Grid>
<h2>Users in queue</h2> <h2>Users in queue</h2>
@ -41,6 +49,11 @@
<Switch Value="context.Active" ValueExpression="() => context.Active" ValueChanged="(value) => SetUserActive(context.Id, value)" /> <Switch Value="context.Active" ValueExpression="() => context.Active" ValueChanged="(value) => SetUserActive(context.Id, value)" />
</ChildContent> </ChildContent>
</GridColumn> </GridColumn>
<GridColumn TItem="User" HeaderText="Revoke">
<ChildContent>
<Button Color="ButtonColor.Danger" @onclick="() => RevokeAccess(context.Id)">Revoke Access</Button>
</ChildContent>
</GridColumn>
</GridColumns> </GridColumns>
</Grid> </Grid>
<h2>Inactive users</h2> <h2>Inactive users</h2>
@ -86,4 +99,19 @@
{ {
Manager.SetUserActive(userId, isActive); Manager.SetUserActive(userId, isActive);
} }
public void RevokeAccess(Guid userId)
{
Manager.RevokeAccess(userId);
}
public void RevokeAllAccess()
{
Manager.RevokeAllAccess();
}
public void Reset()
{
Manager.Reset();
}
} }

View File

@ -16,10 +16,18 @@ namespace AccessQueuePlayground.Services
protected override async Task ExecuteAsync(CancellationToken stoppingToken) protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{ {
while (!stoppingToken.IsCancellationRequested) while (!stoppingToken.IsCancellationRequested)
{
try
{ {
await _accessQueueManager.RecalculateStatus(); await _accessQueueManager.RecalculateStatus();
await Task.Delay(1000, stoppingToken); // Run every second }
} catch (Exception ex)
{
Console.WriteLine(ex);
}
await Task.Delay(100, stoppingToken); // Run every second
}
Console.WriteLine("Stopping now because who tf knows why");
} }
} }
} }

View File

@ -8,7 +8,7 @@ namespace AccessQueuePlayground.Services
public class AccessQueueManager : IAccessQueueManager public class AccessQueueManager : IAccessQueueManager
{ {
private readonly IAccessService _accessService; private readonly IAccessService _accessService;
private readonly ConcurrentDictionary<Guid, User> _users; private ConcurrentDictionary<Guid, User> _users;
private AccessQueueStatus _status; private AccessQueueStatus _status;
public event Action? StatusUpdated; public event Action? StatusUpdated;
@ -39,8 +39,7 @@ namespace AccessQueuePlayground.Services
public void SetUserActive(Guid userId, bool isActive) public void SetUserActive(Guid userId, bool isActive)
{ {
var user = _users[userId]; if (_users.TryGetValue(userId, out var user))
if (user != null)
{ {
user.Active = isActive; user.Active = isActive;
} }
@ -80,5 +79,27 @@ namespace AccessQueuePlayground.Services
_status = newStatus; _status = newStatus;
NotifyStatusUpdated(); NotifyStatusUpdated();
} }
public void RevokeAccess(Guid userId)
{
var user = _users[userId];
user.Active = false;
user.LatestResponse = null;
_accessService.RevokeAccess(userId);
}
public void RevokeAllAccess()
{
foreach (var user in _users.Values)
{
RevokeAccess(user.Id);
}
}
public void Reset()
{
RevokeAllAccess();
_users = [];
}
} }
} }

View File

@ -9,6 +9,9 @@ namespace AccessQueuePlayground.Services
public AccessQueueStatus GetStatus(); public AccessQueueStatus GetStatus();
public Guid AddUser(); public Guid AddUser();
public void SetUserActive(Guid userId, bool isActive); public void SetUserActive(Guid userId, bool isActive);
public void RevokeAccess(Guid userId);
public void RevokeAllAccess();
public void Reset();
} }
} }

View File

@ -68,11 +68,10 @@ namespace AccessQueueService.Data
int filledSpots = 0; int filledSpots = 0;
while (filledSpots < openSpots && _nowServing < _nextUnusedTicket) while (filledSpots < openSpots && _nowServing < _nextUnusedTicket)
{ {
if (_accessQueue.TryGetValue(_nowServing, out var nextUser)) if (_accessQueue.TryGetValue(_nowServing++, out var nextUser))
{ {
_accessQueue.Remove(_nowServing); _accessQueue.Remove(_nowServing);
_queueNumbers.Remove(nextUser.UserId); _queueNumbers.Remove(nextUser.UserId);
_nowServing++;
if (nextUser.LastActive < activeCutoff) if (nextUser.LastActive < activeCutoff)
{ {
// User is inactive, throw away their ticket // User is inactive, throw away their ticket

View File

@ -8,8 +8,6 @@ namespace AccessQueueService.Services
private readonly IConfiguration _configuration; private readonly IConfiguration _configuration;
private readonly IAccessQueueRepo _accessQueueRepo; private readonly IAccessQueueRepo _accessQueueRepo;
//private readonly Dictionary<Guid, AccessTicket> _accessTickets = new();
//private readonly Queue<AccessTicket> _accessQueue = new();
private readonly SemaphoreSlim _queueLock = new(1, 1); private readonly SemaphoreSlim _queueLock = new(1, 1);
private readonly int EXP_SECONDS; private readonly int EXP_SECONDS;
private readonly int ACT_SECONDS; private readonly int ACT_SECONDS;