Skip to content

Commit

Permalink
add cache for white lists
Browse files Browse the repository at this point in the history
  • Loading branch information
NovichikhinAlexey committed Jan 22, 2021
1 parent 2740b3d commit cab5a0c
Show file tree
Hide file tree
Showing 10 changed files with 291 additions and 43 deletions.
130 changes: 103 additions & 27 deletions client/Antares.Service.Assets.Client/AssetsServiceUserDataClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using System.Threading.Tasks;
using Antares.Service.Assets.Client.Models;
using Autofac;
using Common.Log;
using Lykke.Common.Log;
using Lykke.Service.Assets.Client;
using Lykke.Service.Assets.Client.Models;
using Lykke.Service.Assets.Core.Domain;
Expand All @@ -21,14 +23,21 @@ public class AssetsServiceUserDataClient: IStartable, IDisposable, IAssetsServic
private readonly AssetsServiceHttp _httpClient;

private readonly IMyNoSqlServerDataReader<AssetConditionNoSql> _readerAssetConditionNoSql;
private readonly IMyNoSqlServerDataReader<WatchListCustomNoSql> _readerWatchListCustomNoSql;
private MyNoSqlReadRepository<WatchListPredefinedNoSql> _readerWatchListPredefinedNoSql;
private ILog _log;

public AssetsServiceUserDataClient(string myNoSqlServerReaderHostPort, string assetServiceHttpApiUrl)

public AssetsServiceUserDataClient(string myNoSqlServerReaderHostPort, string assetServiceHttpApiUrl, ILogFactory logFactory)
{
_log = logFactory.CreateLog(this);
var host = Environment.GetEnvironmentVariable("HOST") ?? Environment.MachineName;
_httpClient = new AssetsServiceHttp(new Uri(assetServiceHttpApiUrl));

_myNoSqlClient = new MyNoSqlTcpClient(() => myNoSqlServerReaderHostPort, host);
_readerAssetConditionNoSql = new MyNoSqlReadRepository<AssetConditionNoSql>(_myNoSqlClient, AssetConditionNoSql.TableName);
_readerWatchListCustomNoSql = new MyNoSqlReadRepository<WatchListCustomNoSql>(_myNoSqlClient, WatchListCustomNoSql.TableNameCustomWatchList);
_readerWatchListPredefinedNoSql = new MyNoSqlReadRepository<WatchListPredefinedNoSql>(_myNoSqlClient, WatchListPredefinedNoSql.TableNamePredefinedWatchList);
}

public void Start()
Expand All @@ -41,13 +50,13 @@ public void Start()
while (iteration < 100)
{
iteration++;
//if (Assets.GetAll().Count > 0 && AssetExtendedInfo.GetAll().Count > 0 && AssetPairs.GetAll().Count > 0)
break;
if (_readerWatchListPredefinedNoSql.Count() > 0)
break;

Thread.Sleep(100);
}
sw.Stop();
Console.WriteLine($"AssetsWatchLists client is started. Wait time: {sw.ElapsedMilliseconds} ms");
Console.WriteLine($"AssetsServiceUserDataClient client is started. Wait time: {sw.ElapsedMilliseconds} ms");
}

public void Dispose()
Expand All @@ -59,6 +68,29 @@ public void Dispose()
public IAvailableAssetClient AvailableAssets => this;
public IAssetsServiceHttp HttpClient => _httpClient;

async Task<List<string>> IAvailableAssetClient.GetAssetIds(string clientId, bool isIosDevice)
{
try
{
var data = _readerAssetConditionNoSql.Get(
AssetConditionNoSql.GeneratePartitionKey(clientId),
AssetConditionNoSql.GenerateRowKey());

if (data?.AssetConditions != null)
{
return data.AssetConditions.Where(o => o.AvailableToClient == true).Select(o => o.Asset).ToList();
}
}
catch (Exception ex)
{
_log.Error(ex, $"Cannot read from MyNoSQL. Table: ${AssetConditionNoSql.TableName}, PK: {AssetConditionNoSql.GeneratePartitionKey(clientId)}, RK: {AssetConditionNoSql.GenerateRowKey()}");
throw;
}

var result = await HttpClient.ClientGetAssetIdsAsync(clientId, isIosDevice);
return result.ToList();
}

async Task<IWatchList> IWatchListsClient.AddCustomAsync(WatchListDto watchList, string clientId)
{
var result = await HttpClient.WatchListAddCustomAsync(FromWatchListDto(watchList), clientId);
Expand All @@ -76,13 +108,6 @@ async Task IWatchListsClient.RemoveCustomAsync(string watchListId, string client
await HttpClient.WatchListCustomRemoveWithHttpMessagesAsync(watchListId, clientId);
}

async Task<List<IWatchList>> IWatchListsClient.GetAllCustom(string clientId)
{
var result = await HttpClient.WatchListGetAllCustomAsync(clientId);
var data = result.Select(e => (IWatchList) FromWatchListResponse(e)).ToList();
return data;
}

async Task<IWatchList> IWatchListsClient.AddPredefinedAsync(WatchListDto watchList)
{
var result = await HttpClient.WatchListAddPredefinedAsync(FromWatchListDto(watchList));
Expand All @@ -95,41 +120,92 @@ async Task IWatchListsClient.UpdatePredefinedAsync(WatchListDto watchList)
await HttpClient.WatchListUpdatePredefinedAsync(FromWatchListDto(watchList));
}


async Task<IWatchList> IWatchListsClient.GetCustomWatchListAsync(string clientId, string watchListId)
{
var result = await HttpClient.WatchListGetCustomAsync(watchListId, clientId);
var data = FromWatchListResponse(result);
return data;
try
{
var data = _readerWatchListCustomNoSql.Get(WatchListCustomNoSql.GeneratePartitionKey(clientId), WatchListCustomNoSql.GenerateRowKey(watchListId));

if (data != null)
{
return data;
}
}
catch (Exception ex)
{
_log.Error(ex, $"Cannot read from MyNoSQL. Table: ${WatchListCustomNoSql.TableNameCustomWatchList}, PK: {WatchListCustomNoSql.GeneratePartitionKey(clientId)}", ex);
}

try
{
var result = await HttpClient.WatchListGetCustomAsync(watchListId, clientId);
var data = FromWatchListResponse(result);
return data;
}
catch (Exception ex)
{
_log.Error(ex, $"Cannot read from API. Method: WatchListGetCustomAsync, clientId: {clientId}, watchListId: {watchListId}");
throw;
}
}

async Task<IWatchList> IWatchListsClient.GetPredefinedWatchListAsync(string watchListId)
{
var result = await HttpClient.WatchListGetPredefinedAsync(watchListId);
var data = FromWatchListResponse(result);
return data;
try
{
var data = _readerWatchListCustomNoSql.Get(WatchListPredefinedNoSql.GeneratePartitionKey(), WatchListPredefinedNoSql.GenerateRowKey(watchListId));

if (data != null)
{
return data;
}
}
catch (Exception ex)
{
_log.Error(ex, $"Cannot read from MyNoSQL. Table: ${WatchListPredefinedNoSql.TableNamePredefinedWatchList}, PK: {WatchListPredefinedNoSql.GeneratePartitionKey()}, RK: {WatchListPredefinedNoSql.GenerateRowKey(watchListId)}", ex);
}

try
{
var result = await HttpClient.WatchListGetPredefinedAsync(watchListId);
var data = FromWatchListResponse(result);
return data;
}
catch (Exception ex)
{
_log.Error(ex, $"Cannot read from API. Method: WatchListGetPredefinedAsync, watchListId: {watchListId}");
throw;
}
}

async Task<List<string>> IAvailableAssetClient.GetAssetIds(string clientId, bool isIosDevice)
async Task<List<IWatchList>> IWatchListsClient.GetAllCustom(string clientId)
{
try
{
var data = _readerAssetConditionNoSql.Get(
AssetConditionNoSql.GeneratePartitionKey(clientId),
AssetConditionNoSql.GenerateRowKey());
var data = _readerWatchListCustomNoSql.Get(WatchListCustomNoSql.GeneratePartitionKey(clientId));

if (data?.AssetConditions != null)
if (data != null)
{
return data.AssetConditions.Where(o => o.AvailableToClient == true).Select(o => o.Asset).ToList();
return data.Select(e => (IWatchList)e).ToList();
}
}
catch (Exception ex)
{
Console.WriteLine($"Cannot read from MyNoSQL. Table: ${AssetConditionNoSql.TableName}, PK: {AssetConditionNoSql.GeneratePartitionKey(clientId)}, RK: {AssetConditionNoSql.GenerateRowKey()}, Ex: {ex}");
_log.Error(ex, $"Cannot read from MyNoSQL. Table: ${WatchListCustomNoSql.TableNameCustomWatchList}, PK: {WatchListCustomNoSql.GeneratePartitionKey(clientId)}", ex);
}

try
{
var result = await HttpClient.WatchListGetAllCustomAsync(clientId);
var resultData = result.Select(e => (IWatchList) FromWatchListResponse(e)).ToList();
return resultData;
}
catch (Exception ex)
{
_log.Error(ex, $"Cannot read from API. Method: WatchListGetAllCustomAsync, clientId: {clientId}");
throw;
}

var result = await HttpClient.ClientGetAssetIdsAsync(clientId, isIosDevice);
return result.ToList();
}

private WatchListDto FromWatchListResponse(WatchList item)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ public interface IWatchListsClient
Task<IWatchList> AddCustomAsync(WatchListDto watchList, string clientId);
Task UpdateCustomWatchListAsync(string clientId, WatchListDto watchList);
Task RemoveCustomAsync(string watchListId, string clientId);
Task<List<IWatchList>> GetAllCustom(string clientId);

Task<IWatchList> AddPredefinedAsync(WatchListDto watchList);
Task UpdatePredefinedAsync(WatchListDto watchList);

Task<List<IWatchList>> GetAllCustom(string clientId);
Task<IWatchList> GetCustomWatchListAsync(string clientId, string watchListId);
Task<IWatchList> GetPredefinedWatchListAsync(string watchListId);
}
Expand Down
40 changes: 40 additions & 0 deletions src/Lykke.Service.Assets.NoSql/Models/WatchListCustomNoSql.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System.Collections.Generic;
using System.Linq;
using Lykke.Service.Assets.Core.Domain;
using MyNoSqlServer.Abstractions;

namespace Lykke.Service.Assets.NoSql.Models
{
public class WatchListCustomNoSql : MyNoSqlDbEntity, IWatchList
{
public const string TableNameCustomWatchList = "antares.asset.custom-watch-list";

public static string GeneratePartitionKey(string clientId) => clientId;
public static string GenerateRowKey(string watchListId) => watchListId;

public string ClientId { get; set; }

public List<string> AssetIds { get; set; }
public string Id { get; set; }
public string Name { get; set; }
public int Order { get; set; }
public bool ReadOnly { get; set; }

IEnumerable<string> IWatchList.AssetIds => AssetIds;

public static WatchListCustomNoSql Create(string clientId, IWatchList watchList)
{
return new WatchListCustomNoSql()
{
PartitionKey = GeneratePartitionKey(clientId),
RowKey = GenerateRowKey(watchList.Id),
Id = watchList.Id,
Name = watchList.Name,
Order = watchList.Order,
ClientId = clientId,
ReadOnly = watchList.ReadOnly,
AssetIds = watchList.AssetIds.ToList()
};
}
}
}
37 changes: 37 additions & 0 deletions src/Lykke.Service.Assets.NoSql/Models/WatchListPredefinedNoSql.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.Collections.Generic;
using System.Linq;
using Lykke.Service.Assets.Core.Domain;
using MyNoSqlServer.Abstractions;

namespace Lykke.Service.Assets.NoSql.Models
{
public class WatchListPredefinedNoSql : MyNoSqlDbEntity, IWatchList
{
public const string TableNamePredefinedWatchList = "antares.asset.predefined-watch-list";

public static string GeneratePartitionKey() => "predefined";
public static string GenerateRowKey(string watchListId) => watchListId;

public List<string> AssetIds { get; set; }
public string Id { get; set; }
public string Name { get; set; }
public int Order { get; set; }
public bool ReadOnly { get; set; }

IEnumerable<string> IWatchList.AssetIds => AssetIds;

public static WatchListPredefinedNoSql Create(IWatchList watchList)
{
return new WatchListPredefinedNoSql()
{
PartitionKey = GeneratePartitionKey(),
RowKey = GenerateRowKey(watchList.Id),
Id = watchList.Id,
Name = watchList.Name,
Order = watchList.Order,
ReadOnly = watchList.ReadOnly,
AssetIds = watchList.AssetIds.ToList()
};
}
}
}
31 changes: 25 additions & 6 deletions src/Lykke.Service.Assets.Services/AssetConditionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,37 +79,46 @@ public async Task<IAssetDefaultConditionLayer> GetDefaultLayerAsync()
return model;
}

public Task AddAssetConditionAsync(string layerId, IAssetCondition assetCondition)
public async Task AddAssetConditionAsync(string layerId, IAssetCondition assetCondition)
{
return _cachedAssetConditionsService.AddAssetConditionAsync(layerId, assetCondition);
await _myNoSqlWriter.Clear();
await _cachedAssetConditionsService.AddAssetConditionAsync(layerId, assetCondition);
}

public Task UpdateAssetConditionAsync(string layerId, IAssetCondition assetCondition)
public async Task UpdateAssetConditionAsync(string layerId, IAssetCondition assetCondition)
{
return _cachedAssetConditionsService.AddAssetConditionAsync(layerId, assetCondition);
await _myNoSqlWriter.Clear();
await _cachedAssetConditionsService.AddAssetConditionAsync(layerId, assetCondition);
}

public Task DeleteAssetConditionAsync(string layerId, string assetId)
public async Task DeleteAssetConditionAsync(string layerId, string assetId)
{
return _cachedAssetConditionsService.DeleteAssetConditionAsync(layerId, assetId);
await _myNoSqlWriter.Clear();
await _cachedAssetConditionsService.DeleteAssetConditionAsync(layerId, assetId);
}

public async Task AddDefaultAssetConditionAsync(string layerId, IAssetDefaultCondition assetDefaultCondition)
{
await _myNoSqlWriter.Clear();

await _assetDefaultConditionRepository.InsertOrReplaceAsync(layerId, assetDefaultCondition);

await _cacheManager.ClearCacheAsync("Added default asset condition");
}

public async Task UpdateDefaultAssetConditionAsync(string layerId, IAssetDefaultCondition assetDefaultCondition)
{
await _myNoSqlWriter.Clear();

await _assetDefaultConditionRepository.InsertOrReplaceAsync(layerId, assetDefaultCondition);

await _cacheManager.ClearCacheAsync("Updated default asset condition");
}

public async Task DeleteDefaultAssetConditionAsync(string layerId)
{
await _myNoSqlWriter.Clear();

await _assetDefaultConditionRepository.DeleteAsync(layerId);

await _cacheManager.ClearCacheAsync("Deleted default asset condition");
Expand All @@ -122,13 +131,17 @@ public async Task AddLayerAsync(IAssetConditionLayer layer)

public async Task UpdateLayerAsync(IAssetConditionLayer layer)
{
await _myNoSqlWriter.Clear();

await _assetConditionLayerRepository.InsertOrReplaceAsync(layer);

await _cacheManager.ClearCacheAsync("Updated condition layer");
}

public async Task DeleteLayerAsync(string layerId)
{
await _myNoSqlWriter.Clear();

await Task.WhenAll(
_assetConditionLayerLinkClientRepository.RemoveLayerFromClientsAsync(layerId),
_cachedAssetConditionsService.DeleteAssetConditionsAsync(layerId),
Expand All @@ -140,6 +153,8 @@ await Task.WhenAll(

public async Task UpdateDefaultLayerAsync(IAssetConditionLayerSettings settings)
{
await _myNoSqlWriter.Clear();

await _assetDefaultConditionLayerRepository.InsertOrReplaceAsync(settings);

await _cacheManager.ClearCacheAsync("Default asset condition layer changed");
Expand All @@ -165,13 +180,17 @@ public async Task<IEnumerable<IAssetConditionLayer>> GetClientLayers(string clie

public async Task AddClientLayerAsync(string clientId, string layerId)
{
await _myNoSqlWriter.TryDeleteAsync(AssetConditionNoSql.GeneratePartitionKey(clientId), AssetConditionNoSql.GenerateRowKey());

await _assetConditionLayerLinkClientRepository.AddAsync(clientId, layerId);

await _cacheManager.RemoveClientFromCacheAsync(clientId);
}

public async Task RemoveClientLayerAsync(string clientId, string layerId)
{
await _myNoSqlWriter.TryDeleteAsync(AssetConditionNoSql.GeneratePartitionKey(clientId), AssetConditionNoSql.GenerateRowKey());

await _assetConditionLayerLinkClientRepository.RemoveAsync(clientId, layerId);

await _cacheManager.RemoveClientFromCacheAsync(clientId);
Expand Down
Loading

0 comments on commit cab5a0c

Please sign in to comment.