/// <summary> /// Fetches metadata and returns true or false indicating if any work that requires persistence was done /// </summary> /// <param name="provider">The provider.</param> /// <param name="item">The item.</param> /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> /// <exception cref="System.ArgumentNullException"></exception> private async Task <ItemUpdateType?> FetchAsync(BaseMetadataProvider provider, BaseItem item, bool force, CancellationToken cancellationToken) { if (item == null) { throw new ArgumentNullException(); } cancellationToken.ThrowIfCancellationRequested(); // Don't clog up the log with these providers if (!(provider is IDynamicInfoProvider)) { _logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name ?? "--Unknown--"); } // This provides the ability to cancel just this one provider var innerCancellationTokenSource = new CancellationTokenSource(); try { var changed = await provider.FetchAsync(item, force, CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, innerCancellationTokenSource.Token).Token).ConfigureAwait(false); if (changed) { return(provider.ItemUpdateType); } return(null); } catch (OperationCanceledException ex) { _logger.Debug("{0} canceled for {1}", provider.GetType().Name, item.Name); // If the outer cancellation token is the one that caused the cancellation, throw it if (cancellationToken.IsCancellationRequested && ex.CancellationToken == cancellationToken) { throw; } return(null); } catch (Exception ex) { _logger.ErrorException("{0} failed refreshing {1} {2}", ex, provider.GetType().Name, item.Name, item.Path ?? string.Empty); provider.SetLastRefreshed(item, DateTime.UtcNow, ProviderRefreshStatus.Failure); return(ItemUpdateType.Unspecified); } finally { innerCancellationTokenSource.Dispose(); } }
/// <summary> /// Fetches metadata and returns true or false indicating if any work that requires persistence was done /// </summary> /// <param name="provider">The provider.</param> /// <param name="item">The item.</param> /// <param name="force">if set to <c>true</c> [force].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{System.Boolean}.</returns> /// <exception cref="System.ArgumentNullException"></exception> private async Task <bool> FetchAsync(BaseMetadataProvider provider, BaseItem item, bool force, CancellationToken cancellationToken) { if (item == null) { throw new ArgumentNullException(); } cancellationToken.ThrowIfCancellationRequested(); _logger.Info("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name ?? "--Unknown--"); // This provides the ability to cancel just this one provider var innerCancellationTokenSource = new CancellationTokenSource(); OnProviderRefreshBeginning(provider, item, innerCancellationTokenSource); try { return(await provider.FetchAsync(item, force, CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, innerCancellationTokenSource.Token).Token).ConfigureAwait(false)); } catch (OperationCanceledException ex) { _logger.Info("{0} cancelled for {1}", provider.GetType().Name, item.Name); // If the outer cancellation token is the one that caused the cancellation, throw it if (cancellationToken.IsCancellationRequested && ex.CancellationToken == cancellationToken) { throw; } return(false); } catch (Exception ex) { _logger.ErrorException("{0} failed refreshing {1}", ex, provider.GetType().Name, item.Name); provider.SetLastRefreshed(item, DateTime.UtcNow, ProviderRefreshStatus.Failure); return(true); } finally { innerCancellationTokenSource.Dispose(); OnProviderRefreshCompleted(provider, item); } }