pull/1/head
a.bozhenov 5 years ago
parent f5acdbee02
commit 3e26a22c68

@ -1,211 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
using ZeroLevel.Models;
using ZeroLevel.Services.Collections;
namespace ZeroLevel.Network
{
public class DiscoveryClient
: IDiscoveryClient
{
private sealed class DCRouter:
IDisposable
{
private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
private IEnumerable<ServiceEndpointInfo> _empty = Enumerable.Empty<ServiceEndpointInfo>();
private List<ServiceEndpointInfo> _services = new List<ServiceEndpointInfo>();
private Dictionary<string, RoundRobinCollection<ServiceEndpointInfo>> _tableByKey;
private Dictionary<string, RoundRobinCollection<ServiceEndpointInfo>> _tableByGroups;
private Dictionary<string, RoundRobinCollection<ServiceEndpointInfo>> _tableByTypes;
internal void Update(IEnumerable<ServiceEndpointsInfo> records)
{
if (records == null)
{
Log.Warning("[DiscoveryClient] UpdateServiceListInfo. Discrovery response is empty");
return;
}
var services = new List<ServiceEndpointInfo>();
foreach (var service in records)
{
var key = service.ServiceKey.ToUpperInvariant();
var type = service.ServiceType.ToUpperInvariant();
var group = service.ServiceGroup.ToUpperInvariant();
services.AddRange(service.Endpoints.Select(e => new ServiceEndpointInfo { Endpoint = e, Group = group, Key = key, Type = type }));
}
_lock.EnterWriteLock();
try
{
_services = services;
_tableByKey = _services.GroupBy(r => r.Key).ToDictionary(g => g.Key, g => new RoundRobinCollection<ServiceEndpointInfo>(g));
_tableByTypes = _services.GroupBy(r => r.Type).ToDictionary(g => g.Key, g => new RoundRobinCollection<ServiceEndpointInfo>(g));
_tableByGroups = _services.GroupBy(r => r.Group).ToDictionary(g => g.Key, g => new RoundRobinCollection<ServiceEndpointInfo>(g));
}
catch (Exception ex)
{
Log.Error(ex, "[DiscoveryClient] UpdateServiceListInfo. Update local routing table error.");
}
finally
{
_lock.ExitWriteLock();
}
}
public ServiceEndpointInfo GetService(string serviceKey, string endpoint)
{
var key = serviceKey.ToUpperInvariant();
_lock.EnterReadLock();
try
{
if (_tableByKey.ContainsKey(key) && _tableByKey[key].Count > 0)
{
return _tableByKey[key].Find(s => s.Endpoint.Equals(endpoint, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
}
}
finally
{
_lock.ExitReadLock();
}
return null;
}
public IEnumerable<ServiceEndpointInfo> GetServiceEndpoints(string serviceKey)
{
var key = serviceKey.Trim().ToUpperInvariant();
_lock.EnterReadLock();
try
{
if (_tableByKey.ContainsKey(key) && _tableByKey[key].Count > 0)
{
return _tableByKey[key].GetCurrentSeq();
}
}
finally
{
_lock.ExitReadLock();
}
return _empty;
}
public IEnumerable<ServiceEndpointInfo> GetServiceEndpointsByGroup(string serviceGroup)
{
var group = serviceGroup.Trim().ToUpperInvariant();
_lock.EnterReadLock();
try
{
if (_tableByGroups.ContainsKey(group) && _tableByGroups[group].Count > 0)
{
return _tableByGroups[group].GetCurrentSeq();
}
}
finally
{
_lock.ExitReadLock();
}
return _empty;
}
public IEnumerable<ServiceEndpointInfo> GetServiceEndpointsByType(string serviceType)
{
var type = serviceType.Trim().ToUpperInvariant();
_lock.EnterReadLock();
try
{
if (_tableByTypes.ContainsKey(type) && _tableByTypes[type].Count > 0)
{
return _tableByTypes[type].GetCurrentSeq();
}
}
finally
{
_lock.ExitReadLock();
}
return _empty;
}
public void Dispose()
{
_lock.Dispose();
}
}
private readonly DCRouter _router = new DCRouter();
private readonly ExClient _discoveryServerClient;
public DiscoveryClient(ExClient client)
{
_discoveryServerClient = client;
UpdateServiceListInfo();
Sheduller.RemindEvery(TimeSpan.FromSeconds(30), UpdateServiceListInfo);
}
private void UpdateServiceListInfo()
{
_discoveryServerClient.ForceConnect();
if (_discoveryServerClient.Status == SocketClientStatus.Working)
{
try
{
var ir = _discoveryServerClient.Request<IEnumerable<ServiceEndpointsInfo>>("services", records => _router.Update(records));
if (!ir.Success)
{
Log.Warning($"[DiscoveryClient] UpdateServiceListInfo. Error request to inbox 'services'. {ir.Comment}");
}
}
catch (Exception ex)
{
Log.Error(ex, "[DiscoveryClient] UpdateServiceListInfo. Discrovery service response is absent");
}
}
else
{
Log.Warning("[DiscoveryClient] UpdateServiceListInfo. No connection to discovery server");
}
}
public bool Register(ZeroServiceInfo info)
{
_discoveryServerClient.ForceConnect();
if (_discoveryServerClient.Status == SocketClientStatus.Working)
{
bool result = false;
try
{
_discoveryServerClient.Request<ZeroServiceInfo, InvokeResult>("register", info, r =>
{
result = r.Success;
if (!result)
{
Log.Warning($"[DiscoveryClient] Register canceled. Discovery reason: {r.Comment}. Comment: {r.Comment}");
}
});
}
catch (Exception ex)
{
Log.Error(ex, "[DiscoveryClient] Register fault");
}
return result;
}
else
{
Log.Warning("[DiscoveryClient] Register. No connection to discovery server");
return false;
}
}
public IEnumerable<ServiceEndpointInfo> GetServiceEndpoints(string serviceKey) => _router.GetServiceEndpoints(serviceKey);
public IEnumerable<ServiceEndpointInfo> GetServiceEndpointsByGroup(string serviceGroup) => _router.GetServiceEndpointsByGroup(serviceGroup);
public IEnumerable<ServiceEndpointInfo> GetServiceEndpointsByType(string serviceType) => _router.GetServiceEndpointsByType(serviceType);
public ServiceEndpointInfo GetService(string serviceKey, string endpoint) => _router.GetService(serviceKey, endpoint);
public void Dispose()
{
_router.Dispose();
_discoveryServerClient.Dispose();
}
}
}

@ -5,16 +5,17 @@
<Description>Infrastructure layer library</Description> <Description>Infrastructure layer library</Description>
<Authors>ogoun</Authors> <Authors>ogoun</Authors>
<Company>ogoun</Company> <Company>ogoun</Company>
<AssemblyVersion>2.0.9.0</AssemblyVersion> <AssemblyVersion>3.0.0.0</AssemblyVersion>
<PackageReleaseNotes>Append transliteration ru-latin <PackageReleaseNotes>New bootstrap concept
Fix .net core bug https://github.com/dotnet/project-system/issues/589</PackageReleaseNotes> New network layer
No backwards compatibility with previous version</PackageReleaseNotes>
<PackageProjectUrl>https://github.com/ogoun/Zero/wiki</PackageProjectUrl> <PackageProjectUrl>https://github.com/ogoun/Zero/wiki</PackageProjectUrl>
<Copyright>Copyright Ogoun 2019</Copyright> <Copyright>Copyright Ogoun 2019</Copyright>
<PackageLicenseUrl>https://opensource.org/licenses/MIT</PackageLicenseUrl> <PackageLicenseUrl>https://opensource.org/licenses/MIT</PackageLicenseUrl>
<PackageIconUrl>https://raw.githubusercontent.com/ogoun/Zero/master/zero.png</PackageIconUrl> <PackageIconUrl>https://raw.githubusercontent.com/ogoun/Zero/master/zero.png</PackageIconUrl>
<RepositoryUrl>https://github.com/ogoun/Zero</RepositoryUrl> <RepositoryUrl>https://github.com/ogoun/Zero</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType> <RepositoryType>GitHub</RepositoryType>
<Version>2.0.9</Version> <Version>3.0.0</Version>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

Loading…
Cancel
Save

Powered by TurnKey Linux.