Performance optimised with caching and async loads

This commit is contained in:
djbadders 2019-10-13 21:08:48 +01:00
parent 7141b0d2cd
commit 377e443f62
14 changed files with 123 additions and 54 deletions

View File

@ -5,6 +5,7 @@ using System.Globalization;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Diagnostics;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Core.Main.DataObjects.PTMagicData; using Core.Main.DataObjects.PTMagicData;
@ -21,28 +22,13 @@ namespace Core.Main.DataObjects
private PTMagicConfiguration _systemConfiguration = null; private PTMagicConfiguration _systemConfiguration = null;
private TransactionData _transactionData = null; private TransactionData _transactionData = null;
private DateTimeOffset _dateTimeNow = Constants.confMinDate; private DateTimeOffset _dateTimeNow = Constants.confMinDate;
private DateTime _buyLogRefresh = DateTime.UtcNow, _sellLogRefresh = DateTime.UtcNow, _dcaLogRefresh = DateTime.UtcNow, _summaryRefresh = DateTime.UtcNow;
private volatile object _buyLock = new object(), _sellLock = new object(), _dcaLock = new object(), _summaryLock = new object();
public ProfitTrailerData(PTMagicConfiguration systemConfiguration) public ProfitTrailerData(PTMagicConfiguration systemConfiguration)
{ {
_systemConfiguration = systemConfiguration; _systemConfiguration = systemConfiguration;
Parallel.Invoke(() =>
{
_summary = BuildSummaryData(GetDataFromProfitTrailer("api/v2/data/misc"));
},
() =>
{
this.BuildSellLogData(GetDataFromProfitTrailer("/api/v2/data/sales"));
},
() =>
{
this.BuildBuyLogData(GetDataFromProfitTrailer("/api/v2/data/pbl", true));
},
() =>
{
this.BuildDCALogData(GetDataFromProfitTrailer("/api/v2/data/dca", true), GetDataFromProfitTrailer("/api/v2/data/pairs", true), GetDataFromProfitTrailer("/api/v2/data/pending", true), GetDataFromProfitTrailer("/api/v2/data/watchmode", true));
});
// Convert local offset time to UTC // Convert local offset time to UTC
TimeSpan offsetTimeSpan = TimeSpan.Parse(systemConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", "")); TimeSpan offsetTimeSpan = TimeSpan.Parse(systemConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", ""));
_dateTimeNow = DateTimeOffset.UtcNow.ToOffset(offsetTimeSpan); _dateTimeNow = DateTimeOffset.UtcNow.ToOffset(offsetTimeSpan);
@ -52,6 +38,19 @@ namespace Core.Main.DataObjects
{ {
get get
{ {
if (_summary == null || (DateTime.UtcNow > _summaryRefresh))
{
lock (_summaryLock)
{
// Thread double locking
if (_summary == null || (DateTime.UtcNow > _summaryRefresh))
{
_summary = BuildSummaryData(GetDataFromProfitTrailer("api/v2/data/misc"));
_summaryRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1);
}
}
}
return _summary; return _summary;
} }
} }
@ -59,6 +58,20 @@ namespace Core.Main.DataObjects
{ {
get get
{ {
if (_sellLog == null || (DateTime.UtcNow > _sellLogRefresh))
{
lock (_sellLock)
{
// Thread double locking
if (_sellLog == null || (DateTime.UtcNow > _sellLogRefresh))
{
_sellLog.Clear();
this.BuildSellLogData(GetDataFromProfitTrailer("/api/v2/data/sales"));
_sellLogRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.RefreshSeconds - 1);
}
}
}
return _sellLog; return _sellLog;
} }
} }
@ -67,7 +80,7 @@ namespace Core.Main.DataObjects
{ {
get get
{ {
return _sellLog.FindAll(sl => sl.SoldDate.Date == _dateTimeNow.DateTime.Date); return SellLog.FindAll(sl => sl.SoldDate.Date == _dateTimeNow.DateTime.Date);
} }
} }
@ -75,7 +88,7 @@ namespace Core.Main.DataObjects
{ {
get get
{ {
return _sellLog.FindAll(sl => sl.SoldDate.Date == _dateTimeNow.DateTime.AddDays(-1).Date); return SellLog.FindAll(sl => sl.SoldDate.Date == _dateTimeNow.DateTime.AddDays(-1).Date);
} }
} }
@ -83,7 +96,7 @@ namespace Core.Main.DataObjects
{ {
get get
{ {
return _sellLog.FindAll(sl => sl.SoldDate.Date >= _dateTimeNow.DateTime.AddDays(-7).Date); return SellLog.FindAll(sl => sl.SoldDate.Date >= _dateTimeNow.DateTime.AddDays(-7).Date);
} }
} }
@ -91,7 +104,7 @@ namespace Core.Main.DataObjects
{ {
get get
{ {
return _sellLog.FindAll(sl => sl.SoldDate.Date >= _dateTimeNow.DateTime.AddDays(-30).Date); return SellLog.FindAll(sl => sl.SoldDate.Date >= _dateTimeNow.DateTime.AddDays(-30).Date);
} }
} }
@ -99,6 +112,40 @@ namespace Core.Main.DataObjects
{ {
get get
{ {
if (_dcaLog == null || (DateTime.UtcNow > _dcaLogRefresh))
{
lock (_dcaLock)
{
// Thread double locking
if (_dcaLog == null || (DateTime.UtcNow > _dcaLogRefresh))
{
dynamic dcaData = null, pairsData = null, pendingData = null, watchData = null;
_dcaLog.Clear();
Parallel.Invoke(() =>
{
dcaData = GetDataFromProfitTrailer("/api/v2/data/dca", true);
},
() =>
{
pairsData = GetDataFromProfitTrailer("/api/v2/data/pairs", true);
},
() =>
{
pendingData = GetDataFromProfitTrailer("/api/v2/data/pending", true);
},
() =>
{
watchData = GetDataFromProfitTrailer("/api/v2/data/watchmode", true);
});
this.BuildDCALogData(dcaData, pairsData, pendingData, watchData);
_dcaLogRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.BagAnalyzerRefreshSeconds - 1);
}
}
}
return _dcaLog; return _dcaLog;
} }
} }
@ -107,6 +154,20 @@ namespace Core.Main.DataObjects
{ {
get get
{ {
if (_buyLog == null || (DateTime.UtcNow > _buyLogRefresh))
{
lock (_buyLock)
{
// Thread double locking
if (_buyLog == null || (DateTime.UtcNow > _buyLogRefresh))
{
_buyLog.Clear();
this.BuildBuyLogData(GetDataFromProfitTrailer("/api/v2/data/pbl", true));
_buyLogRefresh = DateTime.UtcNow.AddSeconds(_systemConfiguration.GeneralSettings.Monitor.BuyAnalyzerRefreshSeconds - 1);
}
}
}
return _buyLog; return _buyLog;
} }
} }
@ -129,17 +190,17 @@ namespace Core.Main.DataObjects
this.Summary.PendingValue + this.Summary.PendingValue +
this.Summary.DustValue); this.Summary.DustValue);
} }
public double GetPairsBalance() public double GetPairsBalance()
{ {
return return
(this.Summary.PairsValue); (this.Summary.PairsValue);
} }
public double GetDCABalance() public double GetDCABalance()
{ {
return return
(this.Summary.DCAValue); (this.Summary.DCAValue);
} }
public double GetPendingBalance() public double GetPendingBalance()
{ {
return return
(this.Summary.PendingValue); (this.Summary.PendingValue);
@ -169,6 +230,7 @@ namespace Core.Main.DataObjects
string url = string.Format("{0}{1}?token={2}", _systemConfiguration.GeneralSettings.Application.ProfitTrailerMonitorURL, callPath, _systemConfiguration.GeneralSettings.Application.ProfitTrailerServerAPIToken); string url = string.Format("{0}{1}?token={2}", _systemConfiguration.GeneralSettings.Application.ProfitTrailerMonitorURL, callPath, _systemConfiguration.GeneralSettings.Application.ProfitTrailerServerAPIToken);
// Get the data from PT // Get the data from PT
Debug.WriteLine(String.Format("{0} - Calling '{1}'", DateTime.UtcNow, url));
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.AutomaticDecompression = DecompressionMethods.GZip; request.AutomaticDecompression = DecompressionMethods.GZip;
request.KeepAlive = true; request.KeepAlive = true;

View File

@ -21,7 +21,7 @@ namespace Monitor.Pages
private void BindData() private void BindData()
{ {
PTData = new ProfitTrailerData(PTMagicConfiguration); PTData = this.PtDataObject;
} }
} }
} }

View File

@ -21,7 +21,7 @@ namespace Monitor.Pages
private void BindData() private void BindData()
{ {
PTData = new ProfitTrailerData(PTMagicConfiguration); PTData = this.PtDataObject;
} }
} }
} }

View File

@ -19,7 +19,7 @@ namespace Monitor.Pages
private void BindData() private void BindData()
{ {
PTData = new ProfitTrailerData(PTMagicConfiguration); PTData = this.PtDataObject;
} }
} }
} }

View File

@ -30,7 +30,7 @@ namespace Monitor.Pages
private void BindData() private void BindData()
{ {
PTData = new ProfitTrailerData(PTMagicConfiguration); PTData = this.PtDataObject;
// Convert local offset time to UTC // Convert local offset time to UTC
TimeSpan offsetTimeSpan = TimeSpan.Parse(PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", "")); TimeSpan offsetTimeSpan = TimeSpan.Parse(PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", ""));

View File

@ -24,7 +24,7 @@ namespace Monitor.Pages {
private void BindData() { private void BindData() {
DCAMarket = GetStringParameter("m", ""); DCAMarket = GetStringParameter("m", "");
PTData = new ProfitTrailerData(PTMagicConfiguration); PTData = this.PtDataObject;
DCALogData = PTData.DCALog.Find(d => d.Market == DCAMarket); DCALogData = PTData.DCALog.Find(d => d.Market == DCAMarket);

View File

@ -23,7 +23,7 @@ namespace Monitor.Pages {
SortFieldId = GetStringParameter("s", "ProfitPercent"); SortFieldId = GetStringParameter("s", "ProfitPercent");
SortDirection = GetStringParameter("d", "DESC"); SortDirection = GetStringParameter("d", "DESC");
PTData = new ProfitTrailerData(PTMagicConfiguration); PTData = this.PtDataObject;
} }
} }
} }

View File

@ -23,7 +23,7 @@ namespace Monitor.Pages {
SortFieldId = GetStringParameter("s", "ProfitPercent"); SortFieldId = GetStringParameter("s", "ProfitPercent");
SortDirection = GetStringParameter("d", "DESC"); SortDirection = GetStringParameter("d", "DESC");
PTData = new ProfitTrailerData(PTMagicConfiguration); PTData = this.PtDataObject;
} }
} }
} }

View File

@ -28,7 +28,7 @@ namespace Monitor.Pages {
} }
private void BindData() { private void BindData() {
PTData = new ProfitTrailerData(PTMagicConfiguration); PTData = this.PtDataObject;
// Cleanup temp files // Cleanup temp files
FileHelper.CleanupFilesMinutes(PTMagicMonitorBasePath + "wwwroot" + System.IO.Path.DirectorySeparatorChar + "assets" + System.IO.Path.DirectorySeparatorChar + "tmp" + System.IO.Path.DirectorySeparatorChar, 5); FileHelper.CleanupFilesMinutes(PTMagicMonitorBasePath + "wwwroot" + System.IO.Path.DirectorySeparatorChar + "assets" + System.IO.Path.DirectorySeparatorChar + "tmp" + System.IO.Path.DirectorySeparatorChar, 5);

View File

@ -53,15 +53,13 @@
buyDisabled = true; buyDisabled = true;
} }
buyLogEntry.PercChange = @buyLogEntry.PercChange * 100;
<tr> <tr>
@if (mps == null || mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0) { @if (mps == null || mps.ActiveSingleSettings == null || mps.ActiveSingleSettings.Count == 0) {
<th class="align-top"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, buyLogEntry.Market, Model.Summary.MainMarket)" target="_blank">@buyLogEntry.Market</a></th> <th class="align-top"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, buyLogEntry.Market, Model.Summary.MainMarket)" target="_blank">@buyLogEntry.Market</a></th>
} else { } else {
<th class="align-top"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, buyLogEntry.Market, Model.Summary.MainMarket)" target="_blank">@buyLogEntry.Market</a> <i class="fa fa-exclamation-triangle text-highlight" data-toggle="tooltip" data-placement="top" data-html="true" title="@await Component.InvokeAsync("PairIcon", mps)" data-template="<div class='tooltip' role='tooltip'><div class='tooltip-arrow'></div><div class='tooltip-inner pair-tooltip'></div></div>"></i></th> <th class="align-top"><a href="@Core.Helper.SystemHelper.GetMarketLink(Model.PTMagicConfiguration.GeneralSettings.Monitor.LinkPlatform,Model.PTMagicConfiguration.GeneralSettings.Application.Exchange, buyLogEntry.Market, Model.Summary.MainMarket)" target="_blank">@buyLogEntry.Market</a> <i class="fa fa-exclamation-triangle text-highlight" data-toggle="tooltip" data-placement="top" data-html="true" title="@await Component.InvokeAsync("PairIcon", mps)" data-template="<div class='tooltip' role='tooltip'><div class='tooltip-arrow'></div><div class='tooltip-inner pair-tooltip'></div></div>"></i></th>
} }
<td class="text-autocolor">@buyLogEntry.PercChange.ToString("#,#0.00")%</td> <td class="text-autocolor">@string.Format("{0}%", (buyLogEntry.PercChange * 100).ToString("#,#0.00"))</td>
@if (buyDisabled) { @if (buyDisabled) {
<td>@Html.Raw(buyStrategyText)</td> <td>@Html.Raw(buyStrategyText)</td>
} else { } else {

View File

@ -20,7 +20,7 @@ namespace Monitor.Pages {
} }
private void BindData() { private void BindData() {
PTData = new ProfitTrailerData(PTMagicConfiguration); PTData = this.PtDataObject;
// Convert local offset time to UTC // Convert local offset time to UTC
TimeSpan offsetTimeSpan = TimeSpan.Parse(PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", "")); TimeSpan offsetTimeSpan = TimeSpan.Parse(PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.Replace("+", ""));

View File

@ -29,7 +29,7 @@ namespace Monitor.Pages {
salesDateString = GetStringParameter("d", ""); salesDateString = GetStringParameter("d", "");
salesMonthString = GetStringParameter("m", ""); salesMonthString = GetStringParameter("m", "");
PTData = new ProfitTrailerData(PTMagicConfiguration); PTData = this.PtDataObject;
if (!salesDateString.Equals("")) { if (!salesDateString.Equals("")) {
SalesDate = SystemHelper.TextToDateTime(salesDateString, Constants.confMinDate); SalesDate = SystemHelper.TextToDateTime(salesDateString, Constants.confMinDate);

View File

@ -10,6 +10,7 @@ using Core.Helper;
using Core.Main.DataObjects.PTMagicData; using Core.Main.DataObjects.PTMagicData;
using Core.MarketAnalyzer; using Core.MarketAnalyzer;
using System.Diagnostics; using System.Diagnostics;
using Core.Main.DataObjects;
namespace Monitor._Internal namespace Monitor._Internal
{ {
@ -28,6 +29,25 @@ namespace Monitor._Internal
public string NotifyType = ""; public string NotifyType = "";
public string MainFiatCurrencySymbol = "$"; public string MainFiatCurrencySymbol = "$";
private volatile object _ptDataLock = new object();
private static ProfitTrailerData _ptData = null;
// Profit Trailer data accessor object
public ProfitTrailerData PtDataObject
{
get
{
if (_ptData == null)
{
lock (_ptDataLock)
{
_ptData = new ProfitTrailerData(PTMagicConfiguration);
}
}
return _ptData;
}
}
public void PreInit() public void PreInit()
{ {

View File

@ -1,21 +1,10 @@
using System; using System;
using System.IO;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Core.Main; using Core.Main;
using Core.Helper; using Core.Helper;
using Core.Main.DataObjects.PTMagicData;
using Core.MarketAnalyzer;
using Core.ProfitTrailer;
using Microsoft.Extensions.Primitives;
namespace Monitor._Internal namespace Monitor._Internal
{ {
public class BasePageModelSecure : BasePageModel public class BasePageModelSecure : BasePageModel
{ {
public void Init() public void Init()