Compare commits
1 Commits
main
...
calculate-
Author | SHA1 | Date |
---|---|---|
|
b1b1b44e0f |
|
@ -26,6 +26,19 @@ builder.Services.AddHostedService<AccessQueueBackgroundService>();
|
|||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure TakeANumberAccessQueueRepo active users cache
|
||||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
var config = scope.ServiceProvider.GetRequiredService<IConfiguration>();
|
||||
var repo = scope.ServiceProvider.GetRequiredService<IAccessQueueRepo>() as TakeANumberAccessQueueRepo;
|
||||
if (repo != null)
|
||||
{
|
||||
int activeSeconds = config.GetValue<int>("AccessQueue:ActivitySeconds", 2);
|
||||
int updateInterval = config.GetValue<int>("AccessQueue:ActiveUsersUpdateIntervalSeconds", 2);
|
||||
repo.ConfigureActiveUsersCache(activeSeconds, updateInterval);
|
||||
}
|
||||
}
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (!app.Environment.IsDevelopment())
|
||||
{
|
||||
|
|
|
@ -6,13 +6,14 @@
|
|||
}
|
||||
},
|
||||
"AccessQueue": {
|
||||
"CapacityLimit": 3, // Maximum number of active users
|
||||
"ActivitySeconds": 2, // Time since last access before a user is considered inactive
|
||||
"ExpirationSeconds": 10, // 12 hours - Time before a user access is revoked
|
||||
"RollingExpiration": true // Whether to extend expiration time on access
|
||||
"CapacityLimit": 3,
|
||||
"ActivitySeconds": 2,
|
||||
"ExpirationSeconds": 10,
|
||||
"RollingExpiration": true,
|
||||
"ActiveUsersUpdateIntervalSeconds": 2
|
||||
},
|
||||
"AccessQueuePlayground": {
|
||||
"RefreshRateMilliseconds": 200 // How often to re-request access and update the UI
|
||||
"RefreshRateMilliseconds": 200
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using AccessQueueService.Models;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Threading;
|
||||
|
||||
namespace AccessQueueService.Data
|
||||
{
|
||||
|
@ -12,6 +13,12 @@ namespace AccessQueueService.Data
|
|||
private ulong _nowServing = 0;
|
||||
private ulong _nextUnusedTicket = 0;
|
||||
|
||||
private int _cachedActiveUsers = 0;
|
||||
private int _activeSeconds = 60; // default, can be set from config
|
||||
private Timer? _activeUsersUpdateTimer;
|
||||
private int _activeUsersUpdateIntervalSeconds = 10; // default, can be set from config
|
||||
private readonly object _activeUsersLock = new();
|
||||
|
||||
public int GetUnexpiredTicketsCount() => _accessTickets.Count(t => t.Value.ExpiresOn > DateTime.UtcNow);
|
||||
public int GetActiveTicketsCount(DateTime activeCutoff) => _accessTickets
|
||||
.Count(t => t.Value.ExpiresOn > DateTime.UtcNow && t.Value.LastActive > activeCutoff);
|
||||
|
@ -54,7 +61,8 @@ namespace AccessQueueService.Data
|
|||
{
|
||||
var now = DateTime.UtcNow;
|
||||
var activeCutoff = now.AddSeconds(-activeSeconds);
|
||||
var numberOfActiveUsers = _accessTickets.Count(t => t.Value.ExpiresOn > now && t.Value.LastActive > activeCutoff);
|
||||
// Use cached value instead of recalculating
|
||||
var numberOfActiveUsers = GetCachedActiveUsers();
|
||||
var openSpots = capacityLimit - numberOfActiveUsers;
|
||||
if(openSpots <= 0)
|
||||
{
|
||||
|
@ -104,5 +112,33 @@ namespace AccessQueueService.Data
|
|||
}
|
||||
return _accessTickets.Remove(userId);
|
||||
}
|
||||
|
||||
public void ConfigureActiveUsersCache(int activeSeconds, int updateIntervalSeconds)
|
||||
{
|
||||
_activeSeconds = activeSeconds;
|
||||
_activeUsersUpdateIntervalSeconds = updateIntervalSeconds;
|
||||
_activeUsersUpdateTimer?.Dispose();
|
||||
_activeUsersUpdateTimer = new Timer(_ => UpdateActiveUsersCache(), null, 0, _activeUsersUpdateIntervalSeconds * 1000);
|
||||
}
|
||||
|
||||
private void UpdateActiveUsersCache()
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
var activeCutoff = now.AddSeconds(-_activeSeconds);
|
||||
int count = 0;
|
||||
lock (_activeUsersLock)
|
||||
{
|
||||
count = _accessTickets.Count(t => t.Value.ExpiresOn > now && t.Value.LastActive > activeCutoff);
|
||||
_cachedActiveUsers = count;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetCachedActiveUsers()
|
||||
{
|
||||
lock (_activeUsersLock)
|
||||
{
|
||||
return _cachedActiveUsers;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,19 @@ builder.Services.AddHostedService<AccessCleanupBackgroundService>();
|
|||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure TakeANumberAccessQueueRepo active users cache
|
||||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
var config = scope.ServiceProvider.GetRequiredService<IConfiguration>();
|
||||
var repo = scope.ServiceProvider.GetRequiredService<IAccessQueueRepo>() as TakeANumberAccessQueueRepo;
|
||||
if (repo != null)
|
||||
{
|
||||
int activeSeconds = config.GetValue<int>("AccessQueue:ActivitySeconds", 900);
|
||||
int updateInterval = config.GetValue<int>("AccessQueue:ActiveUsersUpdateIntervalSeconds", 10);
|
||||
repo.ConfigureActiveUsersCache(activeSeconds, updateInterval);
|
||||
}
|
||||
}
|
||||
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
"ActivitySeconds": 900,
|
||||
"ExpirationSeconds": 43200,
|
||||
"RollingExpiration": true,
|
||||
"CleanupIntervalSeconds": 60
|
||||
"CleanupIntervalSeconds": 60,
|
||||
"ActiveUsersUpdateIntervalSeconds": 10
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue