From fbf8cc833c441de8890998600be044296acfc783 Mon Sep 17 00:00:00 2001 From: LukePulverenti Luke Pulverenti luke pulverenti Date: Tue, 21 Aug 2012 22:50:59 -0400 Subject: a few more async optimizations --- MediaBrowser.Controller/FFMpeg/FFProbe.cs | 22 ++++----- MediaBrowser.Controller/IO/DirectoryWatchers.cs | 6 +-- MediaBrowser.Controller/Kernel.cs | 37 +++++++-------- MediaBrowser.Controller/Library/ItemController.cs | 54 +++++++++------------- .../Providers/AudioInfoProvider.cs | 14 ++++-- .../Providers/BaseMetadataProvider.cs | 2 +- .../Providers/FolderProviderFromXml.cs | 6 ++- .../Providers/ImageFromMediaLocationProvider.cs | 29 ++++++------ .../Providers/LocalTrailerProvider.cs | 10 ++-- .../Providers/VideoInfoProvider.cs | 11 +++-- MediaBrowser.Controller/Xml/BaseItemXmlParser.cs | 2 - 11 files changed, 90 insertions(+), 103 deletions(-) (limited to 'MediaBrowser.Controller') diff --git a/MediaBrowser.Controller/FFMpeg/FFProbe.cs b/MediaBrowser.Controller/FFMpeg/FFProbe.cs index f5364821c..1a0685a7a 100644 --- a/MediaBrowser.Controller/FFMpeg/FFProbe.cs +++ b/MediaBrowser.Controller/FFMpeg/FFProbe.cs @@ -18,10 +18,7 @@ namespace MediaBrowser.Controller.FFMpeg // Use try catch to avoid having to use File.Exists try { - using (FileStream stream = File.OpenRead(outputCachePath)) - { - return JsonSerializer.DeserializeFromStream(stream); - } + return GetCachedResult(outputCachePath); } catch (FileNotFoundException) { @@ -29,7 +26,12 @@ namespace MediaBrowser.Controller.FFMpeg await Run(item.Path, outputCachePath).ConfigureAwait(false); - using (FileStream stream = File.OpenRead(outputCachePath)) + return GetCachedResult(item.Path); + } + + public static FFProbeResult GetCachedResult(string path) + { + using (FileStream stream = File.OpenRead(path)) { return JsonSerializer.DeserializeFromStream(stream); } @@ -40,10 +42,7 @@ namespace MediaBrowser.Controller.FFMpeg // Use try catch to avoid having to use File.Exists try { - using (FileStream stream = File.OpenRead(outputCachePath)) - { - return JsonSerializer.DeserializeFromStream(stream); - } + return GetCachedResult(outputCachePath); } catch (FileNotFoundException) { @@ -51,10 +50,7 @@ namespace MediaBrowser.Controller.FFMpeg await Run(item.Path, outputCachePath).ConfigureAwait(false); - using (FileStream stream = File.OpenRead(outputCachePath)) - { - return JsonSerializer.DeserializeFromStream(stream); - } + return GetCachedResult(item.Path); } private async static Task Run(string input, string output) diff --git a/MediaBrowser.Controller/IO/DirectoryWatchers.cs b/MediaBrowser.Controller/IO/DirectoryWatchers.cs index 0a96990bf..10d11385e 100644 --- a/MediaBrowser.Controller/IO/DirectoryWatchers.cs +++ b/MediaBrowser.Controller/IO/DirectoryWatchers.cs @@ -86,7 +86,7 @@ namespace MediaBrowser.Controller.IO await ProcessPathChanges(paths).ConfigureAwait(false); } - private async Task ProcessPathChanges(IEnumerable paths) + private Task ProcessPathChanges(IEnumerable paths) { List itemsToRefresh = new List(); @@ -105,11 +105,11 @@ namespace MediaBrowser.Controller.IO return folder != null && folder.IsRoot; })) { - await Kernel.Instance.ReloadRoot().ConfigureAwait(false); + return Kernel.Instance.ReloadRoot(); } else { - await Task.WhenAll(itemsToRefresh.Select(i => Kernel.Instance.ReloadItem(i))).ConfigureAwait(false); + return Task.WhenAll(itemsToRefresh.Select(i => Kernel.Instance.ReloadItem(i))); } } diff --git a/MediaBrowser.Controller/Kernel.cs b/MediaBrowser.Controller/Kernel.cs index a24571d87..fa2baafbc 100644 --- a/MediaBrowser.Controller/Kernel.cs +++ b/MediaBrowser.Controller/Kernel.cs @@ -68,21 +68,17 @@ namespace MediaBrowser.Controller public async override Task Init(IProgress progress) { - await Task.Run(async () => - { - await base.Init(progress).ConfigureAwait(false); + ExtractFFMpeg(); + + await base.Init(progress).ConfigureAwait(false); - progress.Report(new TaskProgress() { Description = "Loading Users", PercentComplete = 15 }); - ReloadUsers(); + progress.Report(new TaskProgress() { Description = "Loading Users", PercentComplete = 15 }); + ReloadUsers(); - progress.Report(new TaskProgress() { Description = "Extracting FFMpeg", PercentComplete = 20 }); - await ExtractFFMpeg().ConfigureAwait(false); + progress.Report(new TaskProgress() { Description = "Loading Media Library", PercentComplete = 25 }); + await ReloadRoot().ConfigureAwait(false); - progress.Report(new TaskProgress() { Description = "Loading Media Library", PercentComplete = 25 }); - await ReloadRoot().ConfigureAwait(false); - - progress.Report(new TaskProgress() { Description = "Loading Complete", PercentComplete = 100 }); - }).ConfigureAwait(false); + progress.Report(new TaskProgress() { Description = "Loading Complete", PercentComplete = 100 }); } protected override void OnComposablePartsLoaded() @@ -245,22 +241,21 @@ namespace MediaBrowser.Controller continue; } - await provider.Fetch(item, args).ConfigureAwait(false); + await provider.FetchAsync(item, args).ConfigureAwait(false); } } + private void ExtractFFMpeg() + { + ExtractFFMpeg(ApplicationPaths.FFMpegPath); + ExtractFFMpeg(ApplicationPaths.FFProbePath); + } + /// /// Run these during Init. /// Can't run do this on-demand because there will be multiple workers accessing them at once and we'd have to lock them /// - private async Task ExtractFFMpeg() - { - // FFMpeg.exe - await ExtractFFMpeg(ApplicationPaths.FFMpegPath).ConfigureAwait(false); - await ExtractFFMpeg(ApplicationPaths.FFProbePath).ConfigureAwait(false); - } - - private async Task ExtractFFMpeg(string exe) + private async void ExtractFFMpeg(string exe) { if (File.Exists(exe)) { diff --git a/MediaBrowser.Controller/Library/ItemController.cs b/MediaBrowser.Controller/Library/ItemController.cs index 9fd77fb0d..f182f43f0 100644 --- a/MediaBrowser.Controller/Library/ItemController.cs +++ b/MediaBrowser.Controller/Library/ItemController.cs @@ -116,14 +116,17 @@ namespace MediaBrowser.Controller.Library if (item != null) { - await Kernel.Instance.ExecuteMetadataProviders(item, args); + await Kernel.Instance.ExecuteMetadataProviders(item, args).ConfigureAwait(false); - var folder = item as Folder; - - if (folder != null) + if (item.IsFolder) { // If it's a folder look for child entities - await AttachChildren(folder, fileSystemChildren).ConfigureAwait(false); + (item as Folder).Children = (await Task.WhenAll(GetChildren(item as Folder, fileSystemChildren)).ConfigureAwait(false)) + .Where(i => i != null).OrderBy(f => + { + return string.IsNullOrEmpty(f.SortName) ? f.Name : f.SortName; + + }); } } @@ -133,27 +136,18 @@ namespace MediaBrowser.Controller.Library /// /// Finds child BaseItems for a given Folder /// - private async Task AttachChildren(Folder folder, LazyFileInfo[] fileSystemChildren) + private Task[] GetChildren(Folder folder, LazyFileInfo[] fileSystemChildren) { - int count = fileSystemChildren.Length; - - Task[] tasks = new Task[count]; + Task[] tasks = new Task[fileSystemChildren.Length]; - for (int i = 0; i < count; i++) + for (int i = 0; i < fileSystemChildren.Length; i++) { var child = fileSystemChildren[i]; tasks[i] = GetItem(child.Path, folder, child.FileInfo); } - BaseItem[] baseItemChildren = await Task.WhenAll(tasks).ConfigureAwait(false); - - // Sort them - folder.Children = baseItemChildren.Where(i => i != null).OrderBy(f => - { - return string.IsNullOrEmpty(f.SortName) ? f.Name : f.SortName; - - }); + return tasks; } /// @@ -216,41 +210,41 @@ namespace MediaBrowser.Controller.Library /// /// Gets a Person /// - public async Task GetPerson(string name) + public Task GetPerson(string name) { string path = Path.Combine(Kernel.Instance.ApplicationPaths.PeoplePath, name); - return await GetImagesByNameItem(path, name).ConfigureAwait(false); + return GetImagesByNameItem(path, name); } /// /// Gets a Studio /// - public async Task GetStudio(string name) + public Task GetStudio(string name) { string path = Path.Combine(Kernel.Instance.ApplicationPaths.StudioPath, name); - return await GetImagesByNameItem(path, name).ConfigureAwait(false); + return GetImagesByNameItem(path, name); } /// /// Gets a Genre /// - public async Task GetGenre(string name) + public Task GetGenre(string name) { string path = Path.Combine(Kernel.Instance.ApplicationPaths.GenrePath, name); - return await GetImagesByNameItem(path, name).ConfigureAwait(false); + return GetImagesByNameItem(path, name); } /// /// Gets a Year /// - public async Task GetYear(int value) + public Task GetYear(int value) { string path = Path.Combine(Kernel.Instance.ApplicationPaths.YearPath, value.ToString()); - return await GetImagesByNameItem(path, value.ToString()).ConfigureAwait(false); + return GetImagesByNameItem(path, value.ToString()); } private ConcurrentDictionary ImagesByNameItemCache = new ConcurrentDictionary(); @@ -258,7 +252,7 @@ namespace MediaBrowser.Controller.Library /// /// Generically retrieves an IBN item /// - private async Task GetImagesByNameItem(string path, string name) + private Task GetImagesByNameItem(string path, string name) where T : BaseEntity, new() { string key = path.ToLower(); @@ -266,12 +260,10 @@ namespace MediaBrowser.Controller.Library // Look for it in the cache, if it's not there, create it if (!ImagesByNameItemCache.ContainsKey(key)) { - T obj = await CreateImagesByNameItem(path, name).ConfigureAwait(false); - ImagesByNameItemCache[key] = obj; - return obj; + ImagesByNameItemCache[key] = CreateImagesByNameItem(path, name); } - return ImagesByNameItemCache[key] as T; + return ImagesByNameItemCache[key] as Task; } /// diff --git a/MediaBrowser.Controller/Providers/AudioInfoProvider.cs b/MediaBrowser.Controller/Providers/AudioInfoProvider.cs index 85a030ddf..64b397a69 100644 --- a/MediaBrowser.Controller/Providers/AudioInfoProvider.cs +++ b/MediaBrowser.Controller/Providers/AudioInfoProvider.cs @@ -23,16 +23,22 @@ namespace MediaBrowser.Controller.Providers get { return MetadataProviderPriority.First; } } - public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args) + public async override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args) { Audio audio = item as Audio; - string outputDirectory = Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeAudioCacheDirectory, item.Id.ToString().Substring(0, 1)); + Fetch(audio, await FFProbe.Run(audio, GetFFProbeOutputPath(item)).ConfigureAwait(false)); + } - string outputPath = Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".js"); + private string GetFFProbeOutputPath(BaseEntity item) + { + string outputDirectory = Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeAudioCacheDirectory, item.Id.ToString().Substring(0, 1)); - FFProbeResult data = await FFProbe.Run(audio, outputPath).ConfigureAwait(false); + return Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".js"); + } + private void Fetch(Audio audio, FFProbeResult data) + { MediaStream stream = data.streams.First(s => s.codec_type.Equals("audio", StringComparison.OrdinalIgnoreCase)); string bitrate = null; diff --git a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs index 6222eec5f..5c536913e 100644 --- a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs +++ b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs @@ -31,7 +31,7 @@ namespace MediaBrowser.Controller.Providers } } - public abstract Task Fetch(BaseEntity item, ItemResolveEventArgs args); + public abstract Task FetchAsync(BaseEntity item, ItemResolveEventArgs args); public abstract MetadataProviderPriority Priority { get; } } diff --git a/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs b/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs index cba41f780..2249fb6a5 100644 --- a/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs +++ b/MediaBrowser.Controller/Providers/FolderProviderFromXml.cs @@ -19,14 +19,16 @@ namespace MediaBrowser.Controller.Providers get { return MetadataProviderPriority.First; } } - public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args) + public override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args) { var metadataFile = args.GetFileSystemEntryByName("folder.xml"); if (metadataFile.HasValue) { - await Task.Run(() => { new FolderXmlParser().Fetch(item as Folder, metadataFile.Value.Path); }).ConfigureAwait(false); + return Task.Run(() => { new FolderXmlParser().Fetch(item as Folder, metadataFile.Value.Path); }); } + + return Task.FromResult(null); } } } diff --git a/MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs b/MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs index 2a5e0394c..59b58474f 100644 --- a/MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs +++ b/MediaBrowser.Controller/Providers/ImageFromMediaLocationProvider.cs @@ -21,24 +21,23 @@ namespace MediaBrowser.Controller.Providers get { return MetadataProviderPriority.First; } } - public override Task Fetch(BaseEntity item, ItemResolveEventArgs args) + public override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args) { - return Task.Run(() => + if (args.IsDirectory) { - if (args.IsDirectory) + var baseItem = item as BaseItem; + + if (baseItem != null) + { + return Task.Run(() => { PopulateImages(baseItem, args); }); + } + else { - var baseItem = item as BaseItem; - - if (baseItem != null) - { - PopulateImages(baseItem, args); - } - else - { - PopulateImages(item, args); - } + return Task.Run(() => { PopulateImages(item, args); }); } - }); + } + + return Task.FromResult(null); } /// @@ -49,7 +48,7 @@ namespace MediaBrowser.Controller.Providers for (int i = 0; i < args.FileSystemChildren.Length; i++) { var file = args.FileSystemChildren[i]; - + string filePath = file.Path; string ext = Path.GetExtension(filePath); diff --git a/MediaBrowser.Controller/Providers/LocalTrailerProvider.cs b/MediaBrowser.Controller/Providers/LocalTrailerProvider.cs index c023edb9a..18ca261dc 100644 --- a/MediaBrowser.Controller/Providers/LocalTrailerProvider.cs +++ b/MediaBrowser.Controller/Providers/LocalTrailerProvider.cs @@ -20,10 +20,8 @@ namespace MediaBrowser.Controller.Providers get { return MetadataProviderPriority.First; } } - public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args) + public async override Task FetchAsync(BaseEntity item, ItemResolveEventArgs args) { - BaseItem baseItem = item as BaseItem; - var trailerPath = args.GetFileSystemEntryByName("trailers", true); if (trailerPath.HasValue) @@ -36,9 +34,7 @@ namespace MediaBrowser.Controller.Providers { string file = allFiles[i]; - BaseItem child = await Kernel.Instance.ItemController.GetItem(file).ConfigureAwait(false); - - Video video = child as Video; + Video video = await Kernel.Instance.ItemController.GetItem(file).ConfigureAwait(false) as Video; if (video != null) { @@ -46,7 +42,7 @@ namespace MediaBrowser.Controller.Providers } } - baseItem.LocalTrailers = localTrailers; + (item as BaseItem).LocalTrailers = localTrailers; } } } diff --git a/MediaBrowser.Controller/Providers/VideoInfoProvider.cs b/MediaBrowser.Controller/Providers/VideoInfoProvider.cs index 5f88aa1cb..96ca8ed35 100644 --- a/MediaBrowser.Controller/Providers/VideoInfoProvider.cs +++ b/MediaBrowser.Controller/Providers/VideoInfoProvider.cs @@ -24,7 +24,7 @@ namespace MediaBrowser.Controller.Providers get { return MetadataProviderPriority.Second; } } - public override async Task Fetch(BaseEntity item, ItemResolveEventArgs args) + public override async Task FetchAsync(BaseEntity item, ItemResolveEventArgs args) { Video video = item as Video; @@ -39,11 +39,14 @@ namespace MediaBrowser.Controller.Providers return; } - string outputDirectory = Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeVideoCacheDirectory, item.Id.ToString().Substring(0, 1)); + Fetch(video, await FFProbe.Run(video, GetFFProbeOutputPath(video)).ConfigureAwait(false)); + } - string outputPath = Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".js"); + private string GetFFProbeOutputPath(Video item) + { + string outputDirectory = Path.Combine(Kernel.Instance.ApplicationPaths.FFProbeVideoCacheDirectory, item.Id.ToString().Substring(0, 1)); - FFProbeResult data = await FFProbe.Run(video, outputPath).ConfigureAwait(false); + return Path.Combine(outputDirectory, item.Id + "-" + item.DateModified.Ticks + ".js"); } private void Fetch(Video video, FFProbeResult data) diff --git a/MediaBrowser.Controller/Xml/BaseItemXmlParser.cs b/MediaBrowser.Controller/Xml/BaseItemXmlParser.cs index f5eecbcde..d39ec6082 100644 --- a/MediaBrowser.Controller/Xml/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Xml/BaseItemXmlParser.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using System.Threading.Tasks; using System.Xml; using MediaBrowser.Model.Entities; -- cgit v1.2.3