feat: Ввел персистентное хранение сотрудников

Реализовал загрузку списка сотрудников с диска при запуске службы.
Добавил методы для сохранения и загрузки сотрудников в файл.
This commit is contained in:
2026-02-01 08:35:24 +03:00
parent c3535cafe9
commit 46c50dc8e2
3 changed files with 32 additions and 29 deletions

View File

@@ -1,4 +1,6 @@
using SfeduSchedule.Logging; using Quartz;
using SfeduSchedule.Jobs;
using System.Text.Json;
namespace SfeduSchedule.Services; namespace SfeduSchedule.Services;
@@ -28,29 +30,8 @@ public class ModeusEmployeeService(ISchedulerFactory schedulerFactory)
_cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); _cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
_backgroundTask = Task.Run(async () => _backgroundTask = Task.Run(async () =>
{ {
try // Загрузка с диска
{ await LoadEmployeesFromDisk();
await Task.Delay(TimeSpan.FromSeconds(15), _cts.Token);
var employees = await modeusService.GetEmployeesAsync();
if (employees.Count == 0)
{
logger.LogWarningHere("Не удалось получить список сотрудников из Modeus.");
}
else
{
_employees = employees;
logger.LogInformationHere($"Получено {employees.Count} сотрудников из Modeus.");
}
}
catch (OperationCanceledException)
{
// ignore
}
catch (Exception ex)
{
logger.LogErrorHere(ex, "Ошибка при загрузке сотрудников из Modeus.");
}
}, _cts.Token); }, _cts.Token);
return Task.CompletedTask; return Task.CompletedTask;
@@ -74,4 +55,26 @@ public class ModeusEmployeeService(ISchedulerFactory schedulerFactory)
// ignore // ignore
} }
} }
public async Task SetEmployees(Dictionary<string, (string, List<string>)> employees)
{
_employees = employees;
await SaveEmployeesToDisk();
}
private async Task LoadEmployeesFromDisk()
{
if (File.Exists(_employeesFilePath))
{
var json = await File.ReadAllTextAsync(_employeesFilePath);
_employees = JsonSerializer.Deserialize<Dictionary<string, (string, List<string>)>>(json) ?? new Dictionary<string, (string, List<string>)>();
}
}
private async Task SaveEmployeesToDisk()
{
var json = JsonSerializer.Serialize(_employees, new JsonSerializerOptions { WriteIndented = false });
await File.WriteAllTextAsync(_employeesFilePath, json);
}
} }

View File

@@ -75,13 +75,13 @@ public class ModeusHttpClient
return []; return [];
} }
public async Task<ModeusSearchPersonResponse?> SearchPersonAsync(ModeusSearchPersonRequest modeusSearchPersonRequest) public async Task<ModeusSearchPersonResponse?> SearchPersonAsync(ModeusSearchPersonRequest modeusSearchPersonRequest, CancellationToken cancellationToken = default)
{ {
using var request = new HttpRequestMessage(HttpMethod.Post, using var request = new HttpRequestMessage(HttpMethod.Post,
$"schedule-calendar-v2/api/people/persons/search"); $"schedule-calendar-v2/api/people/persons/search");
request.Content = JsonContent.Create(modeusSearchPersonRequest, options: GlobalConsts.JsonSerializerOptions); request.Content = JsonContent.Create(modeusSearchPersonRequest, options: GlobalConsts.JsonSerializerOptions);
var stopwatch = Stopwatch.StartNew(); var stopwatch = Stopwatch.StartNew();
using var response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); using var response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
var requestMs = stopwatch.ElapsedMilliseconds; var requestMs = stopwatch.ElapsedMilliseconds;
if (response.StatusCode != System.Net.HttpStatusCode.OK) if (response.StatusCode != System.Net.HttpStatusCode.OK)
{ {
@@ -95,7 +95,7 @@ public class ModeusHttpClient
await using var contentStream = await response.Content.ReadAsStreamAsync(); await using var contentStream = await response.Content.ReadAsStreamAsync();
var content = await JsonSerializer.DeserializeAsync<ModeusSearchPersonResponse>( var content = await JsonSerializer.DeserializeAsync<ModeusSearchPersonResponse>(
contentStream, contentStream,
GlobalConsts.JsonSerializerOptions); GlobalConsts.JsonSerializerOptions, cancellationToken);
var groupMs = stopwatch.ElapsedMilliseconds - deserializeStartMs; var groupMs = stopwatch.ElapsedMilliseconds - deserializeStartMs;
_logger.LogInformationHere($"SearchPersonAsync: Request time: {requestMs} ms, Deserialization time: {groupMs} ms, Total time: {stopwatch.ElapsedMilliseconds} ms."); _logger.LogInformationHere($"SearchPersonAsync: Request time: {requestMs} ms, Deserialization time: {groupMs} ms, Total time: {stopwatch.ElapsedMilliseconds} ms.");

View File

@@ -186,10 +186,10 @@ public class ModeusService(
return serializedCalendar; return serializedCalendar;
} }
public async Task<Dictionary<string, (string, List<string>)>> GetEmployeesAsync() public async Task<Dictionary<string, (string, List<string>)>> GetEmployeesAsync(CancellationToken cancellationToken = default)
{ {
var searchPersonResponse = var searchPersonResponse =
await modeusHttpClient.SearchPersonAsync(new ModeusSearchPersonRequest() { Size = 38000 }); await modeusHttpClient.SearchPersonAsync(new ModeusSearchPersonRequest() { Size = 38000 }, cancellationToken);
if (searchPersonResponse == null) if (searchPersonResponse == null)
{ {
logger.LogErrorHere("persons is null"); logger.LogErrorHere("persons is null");