more profile loading optimizations
This commit is contained in:
parent
6ca94f8da8
commit
2ed5e00bcb
@ -207,42 +207,30 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
|
|
||||||
public async Task<IEnumerable<IClientMeta>> GetRuntimeMeta(ClientPaginationRequest request)
|
public async Task<IEnumerable<IClientMeta>> GetRuntimeMeta(ClientPaginationRequest request)
|
||||||
{
|
{
|
||||||
var meta = new List<IClientMeta>();
|
var metas = await Task.WhenAll(_metaActions.Where(kvp => kvp.Key != MetaType.Information)
|
||||||
|
.Select(async kvp => await kvp.Value[0](request)));
|
||||||
|
|
||||||
foreach (var (type, actions) in _metaActions)
|
return metas.SelectMany(m => (IEnumerable<IClientMeta>)m)
|
||||||
{
|
.OrderByDescending(m => m.When)
|
||||||
// information is not listed chronologically
|
|
||||||
if (type != MetaType.Information)
|
|
||||||
{
|
|
||||||
var metaItems = await actions[0](request);
|
|
||||||
meta.AddRange(metaItems);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return meta.OrderByDescending(_meta => _meta.When)
|
|
||||||
.Take(request.Count)
|
.Take(request.Count)
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<T>> GetRuntimeMeta<T>(ClientPaginationRequest request, MetaType metaType) where T : IClientMeta
|
public async Task<IEnumerable<T>> GetRuntimeMeta<T>(ClientPaginationRequest request, MetaType metaType) where T : IClientMeta
|
||||||
{
|
{
|
||||||
IEnumerable<T> meta;
|
|
||||||
if (metaType == MetaType.Information)
|
if (metaType == MetaType.Information)
|
||||||
{
|
{
|
||||||
var allMeta = new List<T>();
|
var allMeta = new List<T>();
|
||||||
|
|
||||||
foreach (var individualMetaRegistration in _metaActions[metaType])
|
var completedMeta = await Task.WhenAll(_metaActions[metaType].Select(async individualMetaRegistration =>
|
||||||
{
|
(IEnumerable<T>)await individualMetaRegistration(request)));
|
||||||
allMeta.AddRange(await individualMetaRegistration(request));
|
|
||||||
}
|
allMeta.AddRange(completedMeta.SelectMany(meta => meta));
|
||||||
|
|
||||||
return ProcessInformationMeta(allMeta);
|
return ProcessInformationMeta(allMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
var meta = await _metaActions[metaType][0](request) as IEnumerable<T>;
|
||||||
{
|
|
||||||
meta = await _metaActions[metaType][0](request) as IEnumerable<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,6 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
async Task<IEnumerable<InformationResponse>> getStats(ClientPaginationRequest request)
|
async Task<IEnumerable<InformationResponse>> getStats(ClientPaginationRequest request)
|
||||||
{
|
{
|
||||||
IList<EFClientStatistics> clientStats;
|
IList<EFClientStatistics> clientStats;
|
||||||
int messageCount = 0;
|
|
||||||
await using var ctx = _databaseContextFactory.CreateContext(enableTracking: false);
|
await using var ctx = _databaseContextFactory.CreateContext(enableTracking: false);
|
||||||
clientStats = await ctx.Set<EFClientStatistics>().Where(c => c.ClientId == request.ClientId).ToListAsync();
|
clientStats = await ctx.Set<EFClientStatistics>().Where(c => c.ClientId == request.ClientId).ToListAsync();
|
||||||
|
|
||||||
|
@ -168,10 +168,9 @@ namespace SharedLibraryCore.Services
|
|||||||
|
|
||||||
public async Task<EFClient> Get(int entityId)
|
public async Task<EFClient> Get(int entityId)
|
||||||
{
|
{
|
||||||
// todo: this needs to be optimized for large linked accounts
|
|
||||||
await using var context = _contextFactory.CreateContext(false);
|
await using var context = _contextFactory.CreateContext(false);
|
||||||
|
|
||||||
var client = context.Clients
|
var client = await context.Clients
|
||||||
.Select(_client => new EFClient
|
.Select(_client => new EFClient
|
||||||
{
|
{
|
||||||
ClientId = _client.ClientId,
|
ClientId = _client.ClientId,
|
||||||
@ -187,26 +186,28 @@ namespace SharedLibraryCore.Services
|
|||||||
Name = _client.CurrentAlias.Name,
|
Name = _client.CurrentAlias.Name,
|
||||||
IPAddress = _client.CurrentAlias.IPAddress
|
IPAddress = _client.CurrentAlias.IPAddress
|
||||||
},
|
},
|
||||||
TotalConnectionTime = _client.TotalConnectionTime
|
TotalConnectionTime = _client.TotalConnectionTime,
|
||||||
|
AliasLink = new EFAliasLink
|
||||||
|
{
|
||||||
|
AliasLinkId = _client.AliasLinkId,
|
||||||
|
Children = _client.AliasLink.Children
|
||||||
|
},
|
||||||
|
LinkedAccounts = new Dictionary<int, long>()
|
||||||
|
{
|
||||||
|
{_client.ClientId, _client.NetworkId}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.FirstOrDefault(_client => _client.ClientId == entityId);
|
.FirstOrDefaultAsync(_client => _client.ClientId == entityId);
|
||||||
|
|
||||||
if (client == null)
|
if (client == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
client.AliasLink = new EFAliasLink
|
if (!_appConfig.EnableImplicitAccountLinking)
|
||||||
{
|
{
|
||||||
AliasLinkId = client.AliasLinkId,
|
return client;
|
||||||
Children = await context.Aliases
|
}
|
||||||
.Where(_alias => _alias.LinkId == client.AliasLinkId)
|
|
||||||
.Select(_alias => new EFAlias
|
|
||||||
{
|
|
||||||
Name = _alias.Name,
|
|
||||||
IPAddress = _alias.IPAddress
|
|
||||||
}).ToListAsync()
|
|
||||||
};
|
|
||||||
|
|
||||||
var foundClient = new
|
var foundClient = new
|
||||||
{
|
{
|
||||||
@ -220,11 +221,6 @@ namespace SharedLibraryCore.Services
|
|||||||
.ToListAsync()
|
.ToListAsync()
|
||||||
};
|
};
|
||||||
|
|
||||||
if (foundClient == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
foundClient.Client.LinkedAccounts = new Dictionary<int, long>();
|
foundClient.Client.LinkedAccounts = new Dictionary<int, long>();
|
||||||
// todo: find out the best way to do this
|
// todo: find out the best way to do this
|
||||||
// I'm doing this here because I don't know the best way to have multiple awaits in the query
|
// I'm doing this here because I don't know the best way to have multiple awaits in the query
|
||||||
|
@ -163,9 +163,6 @@ namespace SharedLibraryCore.Services
|
|||||||
(p.Expires == null || p.Expires > now);
|
(p.Expires == null || p.Expires > now);
|
||||||
|
|
||||||
await using var context = _contextFactory.CreateContext(false);
|
await using var context = _contextFactory.CreateContext(false);
|
||||||
var iqLinkPenalties = context.Penalties
|
|
||||||
.Where(p => p.LinkId == linkId)
|
|
||||||
.Where(filter);
|
|
||||||
|
|
||||||
IQueryable<EFPenalty> iqIpPenalties;
|
IQueryable<EFPenalty> iqIpPenalties;
|
||||||
|
|
||||||
@ -178,35 +175,6 @@ namespace SharedLibraryCore.Services
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* var aliasIps = await context.Aliases.Where(alias => (alias.LinkId == linkId || alias.AliasId == currentAliasId) && alias.IPAddress != null)
|
|
||||||
.Select(alias => alias.IPAddress)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
if (ip != null)
|
|
||||||
{
|
|
||||||
aliasIps.Add(ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
var clientIds = new List<int>();
|
|
||||||
|
|
||||||
if (aliasIps.Any())
|
|
||||||
{
|
|
||||||
clientIds = await context.Clients.Where(client => aliasIps.Contains(client.CurrentAlias.IPAddress))
|
|
||||||
.Select(client => client.ClientId).ToListAsync();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clientIds.Any())
|
|
||||||
{
|
|
||||||
iqIpPenalties = context.Penalties.Where(penalty => clientIds.Contains(penalty.OffenderId))
|
|
||||||
.Where(filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iqIpPenalties = Enumerable.Empty<EFPenalty>().AsQueryable();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
var usedIps = await context.Aliases.AsNoTracking()
|
var usedIps = await context.Aliases.AsNoTracking()
|
||||||
.Where(alias => (alias.LinkId == linkId || alias.AliasId == currentAliasId) && alias.IPAddress != null)
|
.Where(alias => (alias.LinkId == linkId || alias.AliasId == currentAliasId) && alias.IPAddress != null)
|
||||||
.Select(alias => alias.IPAddress).ToListAsync();
|
.Select(alias => alias.IPAddress).ToListAsync();
|
||||||
@ -216,13 +184,12 @@ namespace SharedLibraryCore.Services
|
|||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
iqIpPenalties = context.Penalties.AsNoTracking()
|
iqIpPenalties = context.Penalties.AsNoTracking()
|
||||||
.Where(penalty => aliasedIds.Contains(penalty.LinkId))
|
.Where(penalty => aliasedIds.Contains(penalty.LinkId) || penalty.LinkId == linkId)
|
||||||
.Where(filter);
|
.Where(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
var activeLinkPenalties = await iqLinkPenalties.ToListAsync();
|
|
||||||
var activeIpPenalties = await iqIpPenalties.ToListAsync();
|
var activeIpPenalties = await iqIpPenalties.ToListAsync();
|
||||||
var activePenalties = activeLinkPenalties.Concat(activeIpPenalties).Distinct();
|
var activePenalties = activeIpPenalties.Distinct();
|
||||||
|
|
||||||
// this is a bit more performant in memory (ordering)
|
// this is a bit more performant in memory (ordering)
|
||||||
return activePenalties.OrderByDescending(p => p.When).ToList();
|
return activePenalties.OrderByDescending(p => p.When).ToList();
|
||||||
|
@ -10,7 +10,6 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Data.Models;
|
using Data.Models;
|
||||||
using IW4MAdmin.Plugins.Stats.Config;
|
|
||||||
using Stats.Config;
|
using Stats.Config;
|
||||||
using WebfrontCore.ViewComponents;
|
using WebfrontCore.ViewComponents;
|
||||||
|
|
||||||
@ -38,7 +37,16 @@ namespace WebfrontCore.Controllers
|
|||||||
|
|
||||||
var activePenalties = await Manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId, client.CurrentAliasId, client.IPAddress);
|
var activePenalties = await Manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId, client.CurrentAliasId, client.IPAddress);
|
||||||
|
|
||||||
var tag = await _metaService.GetPersistentMeta(EFMeta.ClientTag, client);
|
var persistentMetaTask = new[]
|
||||||
|
{
|
||||||
|
_metaService.GetPersistentMeta(EFMeta.ClientTag, client),
|
||||||
|
_metaService.GetPersistentMeta("GravatarEmail", client)
|
||||||
|
};
|
||||||
|
|
||||||
|
var persistentMeta = await Task.WhenAll(persistentMetaTask);
|
||||||
|
var tag = persistentMeta[0];
|
||||||
|
var gravatar = persistentMeta[1];
|
||||||
|
|
||||||
if (tag?.LinkedMeta != null)
|
if (tag?.LinkedMeta != null)
|
||||||
{
|
{
|
||||||
client.SetAdditionalProperty(EFMeta.ClientTag, tag.LinkedMeta.Value);
|
client.SetAdditionalProperty(EFMeta.ClientTag, tag.LinkedMeta.Value);
|
||||||
@ -55,7 +63,7 @@ namespace WebfrontCore.Controllers
|
|||||||
|
|
||||||
displayLevel = string.IsNullOrEmpty(client.Tag) ? displayLevel : $"{displayLevel} ({client.Tag})";
|
displayLevel = string.IsNullOrEmpty(client.Tag) ? displayLevel : $"{displayLevel} ({client.Tag})";
|
||||||
|
|
||||||
var clientDto = new PlayerInfo()
|
var clientDto = new PlayerInfo
|
||||||
{
|
{
|
||||||
Name = client.Name,
|
Name = client.Name,
|
||||||
Level = displayLevel,
|
Level = displayLevel,
|
||||||
@ -92,7 +100,6 @@ namespace WebfrontCore.Controllers
|
|||||||
Before = DateTime.UtcNow
|
Before = DateTime.UtcNow
|
||||||
}, MetaType.Information);
|
}, MetaType.Information);
|
||||||
|
|
||||||
var gravatar = await _metaService.GetPersistentMeta("GravatarEmail", client);
|
|
||||||
if (gravatar != null)
|
if (gravatar != null)
|
||||||
{
|
{
|
||||||
clientDto.Meta.Add(new InformationResponse()
|
clientDto.Meta.Add(new InformationResponse()
|
||||||
@ -106,7 +113,7 @@ namespace WebfrontCore.Controllers
|
|||||||
clientDto.ActivePenalty = activePenalties.OrderByDescending(_penalty => _penalty.Type).FirstOrDefault();
|
clientDto.ActivePenalty = activePenalties.OrderByDescending(_penalty => _penalty.Type).FirstOrDefault();
|
||||||
clientDto.Meta.AddRange(Authorized ? meta : meta.Where(m => !m.IsSensitive));
|
clientDto.Meta.AddRange(Authorized ? meta : meta.Where(m => !m.IsSensitive));
|
||||||
|
|
||||||
string strippedName = clientDto.Name.StripColors();
|
var strippedName = clientDto.Name.StripColors();
|
||||||
ViewBag.Title = strippedName.Substring(strippedName.Length - 1).ToLower()[0] == 's' ?
|
ViewBag.Title = strippedName.Substring(strippedName.Length - 1).ToLower()[0] == 's' ?
|
||||||
strippedName + "'" :
|
strippedName + "'" :
|
||||||
strippedName + "'s";
|
strippedName + "'s";
|
||||||
|
Loading…
Reference in New Issue
Block a user