2022-03-03 13:07:28 +00:00
|
|
|
|
using ASC.Core.Common.Hosting.Interfaces;
|
2022-02-23 12:30:08 +00:00
|
|
|
|
|
|
|
|
|
using Microsoft.Extensions.Hosting;
|
|
|
|
|
|
2022-02-24 14:15:39 +00:00
|
|
|
|
namespace ASC.Core.Common.Hosting;
|
2022-02-23 12:30:08 +00:00
|
|
|
|
|
|
|
|
|
[Scope]
|
2022-02-24 14:15:39 +00:00
|
|
|
|
public class RegisterInstanceManager<T> : IRegisterInstanceManager<T> where T : IHostedService
|
2022-02-23 12:30:08 +00:00
|
|
|
|
{
|
2022-02-24 14:15:39 +00:00
|
|
|
|
private readonly IRegisterInstanceDao<T> _registerInstanceRepository;
|
2022-02-23 12:30:08 +00:00
|
|
|
|
private readonly int _timeUntilUnregisterInSeconds;
|
2022-02-24 14:15:39 +00:00
|
|
|
|
public RegisterInstanceManager(IRegisterInstanceDao<T> registerInstanceRepository,
|
2022-02-23 12:30:08 +00:00
|
|
|
|
IConfiguration configuration)
|
|
|
|
|
{
|
|
|
|
|
_registerInstanceRepository = registerInstanceRepository;
|
|
|
|
|
|
2022-02-24 14:15:39 +00:00
|
|
|
|
if (!int.TryParse(configuration["core:hosting:timeUntilUnregisterInSeconds"], out _timeUntilUnregisterInSeconds))
|
2022-02-23 12:30:08 +00:00
|
|
|
|
{
|
2022-03-03 13:07:28 +00:00
|
|
|
|
_timeUntilUnregisterInSeconds = 15;
|
2022-02-23 12:30:08 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public async Task Register(string instanceId)
|
|
|
|
|
{
|
|
|
|
|
var instances = await _registerInstanceRepository.GetAll();
|
|
|
|
|
var registeredInstance = instances.FirstOrDefault(x => x.InstanceRegistrationId == instanceId);
|
|
|
|
|
|
2022-03-03 13:07:28 +00:00
|
|
|
|
var instance = registeredInstance ?? new InstanceRegistration
|
|
|
|
|
{
|
|
|
|
|
InstanceRegistrationId = instanceId,
|
|
|
|
|
WorkerTypeName = typeof(T).Name
|
|
|
|
|
};
|
|
|
|
|
|
2022-02-23 12:30:08 +00:00
|
|
|
|
instance.LastUpdated = DateTime.UtcNow;
|
2022-03-03 13:07:28 +00:00
|
|
|
|
|
|
|
|
|
if (instances.Any() && !instances.Any(x => x.IsActive))
|
2022-02-23 12:30:08 +00:00
|
|
|
|
{
|
2022-03-03 13:07:28 +00:00
|
|
|
|
if (GetFirstAliveInstance(instances).InstanceRegistrationId == instance.InstanceRegistrationId)
|
|
|
|
|
{
|
|
|
|
|
instance.IsActive = true;
|
|
|
|
|
}
|
2022-02-23 12:30:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-03-03 13:07:28 +00:00
|
|
|
|
await _registerInstanceRepository.AddOrUpdate(instance);
|
2022-02-23 12:30:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task UnRegister(string instanceId)
|
|
|
|
|
{
|
|
|
|
|
await _registerInstanceRepository.Delete(instanceId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<bool> IsActive(string instanceId)
|
|
|
|
|
{
|
|
|
|
|
var instances = await _registerInstanceRepository.GetAll();
|
|
|
|
|
var instance = instances.FirstOrDefault(x => x.InstanceRegistrationId == instanceId);
|
|
|
|
|
|
|
|
|
|
return instance is not null && instance.IsActive;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<List<string>> DeleteOrphanInstances()
|
|
|
|
|
{
|
|
|
|
|
var instances = await _registerInstanceRepository.GetAll();
|
2022-03-03 13:07:28 +00:00
|
|
|
|
var oldRegistrations = instances.Where(IsOrphanInstance).ToList();
|
2022-02-23 12:30:08 +00:00
|
|
|
|
|
|
|
|
|
foreach (var instanceRegistration in oldRegistrations)
|
|
|
|
|
{
|
|
|
|
|
await _registerInstanceRepository.Delete(instanceRegistration.InstanceRegistrationId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return oldRegistrations.Select(x => x.InstanceRegistrationId).ToList();
|
|
|
|
|
}
|
2022-03-03 13:07:28 +00:00
|
|
|
|
|
|
|
|
|
private InstanceRegistration GetFirstAliveInstance(IEnumerable<InstanceRegistration> instances)
|
|
|
|
|
{
|
|
|
|
|
Func<InstanceRegistration, long> _getTicksCreationService = x => Convert.ToInt64(x.InstanceRegistrationId.Split('_')[1]);
|
|
|
|
|
|
|
|
|
|
return instances.Where(x => !IsOrphanInstance(x)).MinBy(_getTicksCreationService);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool IsOrphanInstance(InstanceRegistration obj)
|
|
|
|
|
{
|
|
|
|
|
return obj.LastUpdated.Value.AddSeconds(_timeUntilUnregisterInSeconds) < DateTime.UtcNow;
|
|
|
|
|
}
|
2022-02-23 12:30:08 +00:00
|
|
|
|
}
|