Files
C4IT-F4SD-Client/FasdDesktopUi/Basics/Services/RelationService/RelationService.cs
Meik 0b52999b1d feat: expand cockpit integrations and support workflows
Add Phoenix remote desktop, action connector, documentation engine, and gamification support. Refactor support-case processing and search/action UI, and update installer assets and dependencies.
2026-07-13 11:16:53 +02:00

111 lines
4.3 KiB
C#

using C4IT.FASD.Base;
using C4IT.FASD.Cockpit.Communication;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using static C4IT.Logging.cLogManager;
[assembly: InternalsVisibleTo("F4SD.Cockpit.Client.Test")]
namespace FasdDesktopUi.Basics.Services.RelationService
{
internal class RelationService : IRelationService
{
private readonly object _relationsLock = new object();
private IEnumerable<cF4sdApiSearchResultRelation> _relations = new List<cF4sdApiSearchResultRelation>();
public void Reset()
{
lock (_relationsLock)
_relations = _relations.Where(r => r.Type == enumF4sdSearchResultClass.User).ToList();
RelationsReset?.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// Asynchronously loads relations for the specified search results.
/// </summary>
/// <remarks>This method initiates a task to gather relations for the provided search results and
/// periodically checks for the completion of the task. Once relations are retrieved, an event <see cref="RelationsFound"/>
/// is raised to notify listeners of the progress.</remarks>
/// <returns>Task id and pending information classes</returns>
public async Task<cF4sdStagedSearchResultRelationTaskId> LoadRelationsAsync(IEnumerable<cFasdApiSearchResultEntry> relatedTo, CancellationToken token = default)
{
try
{
lock (_relationsLock)
_relations = relatedTo?.Select(searchResult => new cF4sdApiSearchResultRelation(searchResult)).ToList() ?? new List<cF4sdApiSearchResultRelation>();
cF4sdStagedSearchResultRelationTaskId gatherRelationTask = await cFasdCockpitCommunicationBase.Instance.StartGatheringRelations(relatedTo, token);
if (gatherRelationTask is null)
return null;
_ = Task.Run(async () => await GatherRelationsAsync(gatherRelationTask.Id, relatedTo, token));
return gatherRelationTask;
}
catch (Exception ex)
{
LogException(ex);
}
return null;
}
private async Task GatherRelationsAsync(Guid gatherTaskId, IEnumerable<cFasdApiSearchResultEntry> relatedTo, CancellationToken token = default)
{
try
{
const int maxRetryCount = 10;
for (int i = 0; i < maxRetryCount; i++)
{
if (token.IsCancellationRequested)
{
await cFasdCockpitCommunicationBase.Instance.StopGatheringRelations(gatherTaskId, CancellationToken.None);
return;
}
cF4sdStagedSearchResultRelations stagedRelations = await cFasdCockpitCommunicationBase.Instance.GetStagedRelations(gatherTaskId, token);
if (stagedRelations is null)
continue;
stagedRelations.MergeAsRelationInfosWith(relatedTo);
lock (_relationsLock)
_relations = _relations.Union(stagedRelations.Relations).ToList();
RelationsFound?.Invoke(this, new StagedSearchResultRelationsEventArgs() { RelatedTo = relatedTo, StagedResultRelations = stagedRelations, RelationService = this });
if (stagedRelations?.IsComplete ?? false)
break;
}
}
catch (Exception ex)
{
LogException(ex);
}
}
public IReadOnlyList<cF4sdApiSearchResultRelation> GetLoadedRelations()
{
lock (_relationsLock)
return _relations.ToList();
}
public IRelationService Clone()
{
RelationService copy = new RelationService();
lock (_relationsLock)
copy._relations = _relations.ToList();
return copy;
}
public event EventHandler RelationsReset;
public event EventHandler<StagedSearchResultRelationsEventArgs> RelationsFound;
}
}