Performance related for track streaming.

This commit is contained in:
Steven Hildreth 2019-01-13 11:27:41 -06:00
parent dea9001fd5
commit 6c23634b2f
3 changed files with 51 additions and 13 deletions

View file

@ -14,6 +14,8 @@ namespace Roadie.Api.Services
Task<Library.Models.Pagination.PagedResult<TrackList>> List(PagedRequest request, User roadieUser, bool? doRandomize = false, Guid? releaseId = null);
OperationResult<Track> StreamCheckAndInfo(User roadieUser, Guid id);
Task<OperationResult<TrackStreamInfo>> TrackStreamInfo(Guid trackId, long beginBytes, long endBytes);
}
}

View file

@ -185,7 +185,7 @@ namespace Roadie.Api.Services
}
int[] collectionTrackIds = new int[0];
if(request.FilterToCollectionId.HasValue)
if (request.FilterToCollectionId.HasValue)
{
request.Limit = roadieUser?.PlayerTrackLimit ?? 50;
@ -195,7 +195,7 @@ namespace Roadie.Api.Services
join rm in this.DbContext.ReleaseMedias on r.Id equals rm.ReleaseId
join t in this.DbContext.Tracks on rm.Id equals t.ReleaseMediaId
where c.RoadieId == request.FilterToCollectionId.Value
orderby cr.ListNumber, rm.MediaNumber, t.TrackNumber
orderby cr.ListNumber, rm.MediaNumber, t.TrackNumber
select t.Id).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
}
@ -214,8 +214,8 @@ namespace Roadie.Api.Services
).Skip(request.SkipValue).Take(request.LimitValue).ToArray();
}
int[] randomTrackIds = null;
if (doRandomize ?? false) {
if (doRandomize ?? false)
{
request.Limit = roadieUser?.RandomReleaseLimit ?? 50;
if (!request.FilterRatedOnly && !request.FilterFavoriteOnly)
@ -226,7 +226,7 @@ namespace Roadie.Api.Services
"ORDER BY RAND() LIMIT {0}";
randomTrackIds = this.DbContext.Tracks.FromSql(sql, request.LimitValue).Select(x => x.Id).ToArray();
}
if(request.FilterRatedOnly && !request.FilterFavoriteOnly)
if (request.FilterRatedOnly && !request.FilterFavoriteOnly)
{
var sql = "SELECT t.* " +
"FROM `track` t " +
@ -235,7 +235,7 @@ namespace Roadie.Api.Services
"ORDER BY RAND() LIMIT {0}";
randomTrackIds = this.DbContext.Tracks.FromSql(sql, request.LimitValue).Select(x => x.Id).ToArray();
}
if(request.FilterFavoriteOnly)
if (request.FilterFavoriteOnly)
{
randomTrackIds = favoriteTrackIds.OrderBy(x => Guid.NewGuid()).ToArray();
}
@ -519,6 +519,23 @@ namespace Roadie.Api.Services
}
}
/// <summary>
/// Fast as possible check if exists and return minimum information on Track
/// </summary>
public OperationResult<Track> StreamCheckAndInfo(User roadieUser, Guid id)
{
var track = this.DbContext.Tracks.FirstOrDefault(x => x.RoadieId == id);
if (track == null)
{
return new OperationResult<Track>(true, string.Format("Track Not Found [{0}]", id));
}
return new OperationResult<Track>()
{
Data = track.Adapt<Track>(),
IsSuccess = true
};
}
public async Task<OperationResult<TrackStreamInfo>> TrackStreamInfo(Guid trackId, long beginBytes, long endBytes)
{
var track = this.GetTrack(trackId);

View file

@ -4,11 +4,14 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Roadie.Api.Services;
using Roadie.Library.Caching;
using Roadie.Library.Configuration;
using Roadie.Library.Identity;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
@ -64,8 +67,13 @@ namespace Roadie.Api.Controllers
protected async Task<IActionResult> StreamTrack(Guid id, ITrackService trackService, IPlayActivityService playActivityService, models.User currentUser = null)
{
var sw = Stopwatch.StartNew();
var timings = new Dictionary<string, long>();
var tsw = new Stopwatch();
tsw.Restart();
var user = currentUser ?? await this.CurrentUserModel();
var track = await trackService.ById(user, id, null);
var track = trackService.StreamCheckAndInfo(user, id);
if (track == null || ( track?.IsNotFoundResult ?? false))
{
if (track?.Errors != null && (track?.Errors.Any() ?? false))
@ -78,6 +86,10 @@ namespace Roadie.Api.Controllers
}
return NotFound("Unknown TrackId");
}
tsw.Stop();
timings.Add("TrackService.StreamCheckAndInfo", tsw.ElapsedMilliseconds);
tsw.Restart();
var info = await trackService.TrackStreamInfo(id,
Services.TrackService.DetermineByteStartFromHeaders(this.Request.Headers),
Services.TrackService.DetermineByteEndFromHeaders(this.Request.Headers, track.Data.FileSize));
@ -93,6 +105,10 @@ namespace Roadie.Api.Controllers
}
return NotFound("Unknown TrackId");
}
tsw.Stop();
timings.Add("TrackStreamInfo", tsw.ElapsedMilliseconds);
tsw.Restart();
Response.Headers.Add("Content-Disposition", info.Data.ContentDisposition);
Response.Headers.Add("X-Content-Duration", info.Data.ContentDuration);
if (!info.Data.IsFullRequest)
@ -107,13 +123,16 @@ namespace Roadie.Api.Controllers
Response.Headers.Add("ETag", info.Data.Etag);
Response.Headers.Add("Cache-Control", info.Data.CacheControl);
Response.Headers.Add("Expires", info.Data.Expires);
var stream = new MemoryStream(info.Data.Bytes);
var playListUser = await playActivityService.CreatePlayActivity(user, info.Data);
this.Logger.LogInformation($"StreamTrack PlayActivity `{ playListUser?.Data.ToString() }`, StreamInfo `{ info.Data.ToString() }`");
return new FileStreamResult(stream, info.Data.ContentType)
{
FileDownloadName = info.Data.FileName
};
await Response.Body.WriteAsync(info.Data.Bytes, 0, info.Data.Bytes.Length);
var playListUser = await playActivityService.CreatePlayActivity(user, info?.Data);
sw.Stop();
this.Logger.LogInformation($"StreamTrack ElapsedTime [{ sw.ElapsedMilliseconds }], Timings [{ JsonConvert.SerializeObject(timings) }] PlayActivity `{ playListUser?.Data.ToString() }`, StreamInfo `{ info?.Data.ToString() }`");
return new EmptyResult();
}
}
}