Add option to run playground against separate API

This commit is contained in:
henry 2025-07-04 15:18:02 -04:00
parent 192dd67f52
commit d549f99c67
4 changed files with 103 additions and 8 deletions

View File

@ -19,7 +19,15 @@ builder.Host.UseSerilog((context, services, configuration) =>
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
builder.Services.AddSingleton<IAccessService, AccessService>();
if (string.IsNullOrEmpty(builder.Configuration["AccessQueuePlayground:ServiceUrl"]))
{
builder.Services.AddSingleton<IAccessService, AccessService>();
}
else
{
builder.Services.AddHttpClient();
builder.Services.AddSingleton<IAccessService, AccessQueueApiService>();
}
builder.Services.AddSingleton<IAccessQueueRepo, TakeANumberAccessQueueRepo>();
builder.Services.AddSingleton<IAccessQueueManager, AccessQueueManager>();
builder.Services.AddHostedService<AccessQueueBackgroundService>();

View File

@ -0,0 +1,59 @@
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using AccessQueueService.Models;
using AccessQueueService.Services;
namespace AccessQueuePlayground.Services
{
public class AccessQueueApiService : IAccessService
{
private readonly HttpClient _httpClient;
private readonly string _serviceUrl;
public AccessQueueStatus Status => throw new NotImplementedException();
public AccessQueueApiService(HttpClient httpClient, IConfiguration config)
{
_httpClient = httpClient;
_serviceUrl = config["AccessQueuePlayground:ServiceUrl"]?.TrimEnd('/') ?? "https://localhost:7291";
}
public async Task<AccessResponse> RequestAccess(string userId)
{
return await _httpClient.GetFromJsonAsync<AccessResponse>($"{_serviceUrl}/access/{userId}");
}
public async Task<bool> RevokeAccess(string userId)
{
var response = await _httpClient.DeleteAsync($"{_serviceUrl}/access/{userId}");
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadFromJsonAsync<bool>();
return result;
}
return false;
}
public Task<int> DeleteExpiredTickets()
{
throw new NotImplementedException();
}
public AccessQueueConfig GetConfiguration()
{
return _httpClient.GetFromJsonAsync<AccessQueueConfig>($"{_serviceUrl}/config").Result;
}
public void UpdateConfiguration(AccessQueueConfig config)
{
_ = _httpClient.PostAsJsonAsync($"{_serviceUrl}/config", config).Result;
}
public void PatchConfiguration(AccessQueueConfig partialConfig)
{
throw new NotImplementedException();
}
}
}

View File

@ -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
},
"AccessQueuePlayground": {
"RefreshRateMilliseconds": 200 // How often to re-request access and update the UI
"RefreshRateMilliseconds": 200,
"ServiceUrl": "https://localhost:7291/"
},
"AllowedHosts": "*"
}

View File

@ -155,7 +155,7 @@ Test results will be displayed in the terminal. You can also use Visual Studio's
The `AccessQueuePlayground` project provides a simple web-based UI for interacting with the AccessQueueService API. This is useful for testing and demonstration purposes.
### Running the Playground
### Running
1. Build and run the playground project:
```powershell
@ -166,7 +166,7 @@ The `AccessQueuePlayground` project provides a simple web-based UI for interacti
- HTTPS: https://localhost:7211
(See `AccessQueuePlayground/Properties/launchSettings.json` for details.)
### Using the Playground
### Using
- Open the provided URL in your browser.
- Use the UI to request and revoke access for different user IDs.
@ -174,5 +174,32 @@ The `AccessQueuePlayground` project provides a simple web-based UI for interacti
This playground is intended only for local development and demonstration.
### Configuring
The `AccessQueuePlayground` project can be configured via its `appsettings.json` file. The main options are:
- **RefreshRateMilliseconds**: Determines how often (in milliseconds) the playground requests access for all active users and updates the UI. Lower values provide more real-time updates but may increase load on the service.
- **ServiceUrl**: The URL of the AccessQueueService API to use. If this is set, all API requests from the playground will be sent to the specified service URL (e.g., `https://localhost:7291/`).
- If `ServiceUrl` is **not provided**, the playground will use an internal instance of AccessQueueService, configured using the playground's own `appsettings.json` values under the `AccessQueue` section. This is useful for local development and testing without running the service separately.
Example configuration in `AccessQueuePlayground/appsettings.json`:
```json
{
"AccessQueuePlayground": {
"RefreshRateMilliseconds": 200,
"ServiceUrl": "https://localhost:7291/"
},
"AccessQueue": {
"CapacityLimit": 3,
"ActivitySeconds": 2,
"ExpirationSeconds": 10,
"RollingExpiration": true
}
}
```
> **Tip:** Adjust `RefreshRateMilliseconds` for your use case. For most demos, 100500ms works well. If you are connecting to a remote or production AccessQueueService, consider increasing the refresh interval (e.g., 1000ms or higher) to account for network latency and reduce unnecessary load.
## License
See [LICENSE.txt](./LICENSE.txt) for license information.