Untis-API Optimierung.
This commit is contained in:
@@ -9,6 +9,7 @@ public sealed class WebUntisClient : IAsyncDisposable
|
||||
{
|
||||
private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web);
|
||||
private static readonly UTF8Encoding StrictUtf8 = new(false, true);
|
||||
private static readonly TimeSpan LogoutTimeout = TimeSpan.FromSeconds(2);
|
||||
private readonly HttpClient _http;
|
||||
private readonly WebUntisOptions _options;
|
||||
private readonly SemaphoreSlim _sessionGate = new(1, 1);
|
||||
@@ -177,7 +178,7 @@ public sealed class WebUntisClient : IAsyncDisposable
|
||||
Entities(entry, "ro"), entry.Clone())).ToList();
|
||||
}, cancellationToken);
|
||||
|
||||
public Task<UntisStudentAbsenceReport> GetStudentAbsencesAsync(int studentKey, int startDate, int endDate,
|
||||
public Task<IReadOnlyList<UntisStudentAbsence>> GetAbsencesAsync(int startDate, int endDate,
|
||||
CancellationToken cancellationToken) => WithSessionAsync(async sessionId =>
|
||||
{
|
||||
var result = await RpcAsync("getTimetableWithAbsences", new
|
||||
@@ -187,8 +188,7 @@ public sealed class WebUntisClient : IAsyncDisposable
|
||||
if (!TryProperty(result, "periodsWithAbsences", out var periods) || periods.ValueKind != JsonValueKind.Array)
|
||||
throw new WebUntisException("WebUntis hat keine gültigen Fehlzeiten-Daten geliefert.");
|
||||
|
||||
var absences = periods.EnumerateArray()
|
||||
.Where(entry => OptionalInt(entry, "studentId") == studentKey)
|
||||
return (IReadOnlyList<UntisStudentAbsence>)periods.EnumerateArray()
|
||||
.Select(entry => new UntisStudentAbsence(
|
||||
RequiredInt(entry, "studentId"),
|
||||
RequiredInt(entry, "date"),
|
||||
@@ -205,9 +205,6 @@ public sealed class WebUntisClient : IAsyncDisposable
|
||||
.OrderBy(entry => entry.Date)
|
||||
.ThenBy(entry => entry.StartTime)
|
||||
.ToList();
|
||||
|
||||
return new UntisStudentAbsenceReport(studentKey, startDate, endDate, absences.Count,
|
||||
absences.Sum(entry => entry.AbsentMinutes), absences);
|
||||
}, cancellationToken);
|
||||
|
||||
public Task<IReadOnlyList<UntisClassRegisterEntry>> GetClassRegisterEntriesAsync(int studentId,
|
||||
@@ -346,14 +343,15 @@ public sealed class WebUntisClient : IAsyncDisposable
|
||||
|
||||
private async Task TryLogoutAsync(string sessionId)
|
||||
{
|
||||
try { await RpcAsync("logout", new { }, sessionId, CancellationToken.None); }
|
||||
using var timeout = new CancellationTokenSource(LogoutTimeout);
|
||||
try { await RpcAsync("logout", new { }, sessionId, timeout.Token).ConfigureAwait(false); }
|
||||
catch { /* Ein fehlgeschlagener Logout darf Abrufe und Shutdown nicht fehlschlagen lassen. */ }
|
||||
}
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
string? sessionId;
|
||||
await _sessionGate.WaitAsync();
|
||||
await _sessionGate.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
if (_disposed) return;
|
||||
@@ -368,8 +366,8 @@ public sealed class WebUntisClient : IAsyncDisposable
|
||||
|
||||
// Außerhalb des Gates warten: ein bereits laufender Timer-Callback könnte selbst gerade
|
||||
// auf dieses Gate warten und würde sonst den Shutdown blockieren.
|
||||
await _sessionExpiryTimer.DisposeAsync();
|
||||
if (sessionId is not null) await TryLogoutAsync(sessionId);
|
||||
await _sessionExpiryTimer.DisposeAsync().ConfigureAwait(false);
|
||||
if (sessionId is not null) await TryLogoutAsync(sessionId).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private TimeSpan SessionIdleTimeout =>
|
||||
|
||||
Reference in New Issue
Block a user