コード例 #1
0
ファイル: PluginManager.cs プロジェクト: dslzuha/nugetclient
        /// <summary>
        /// Creates a plugin from the discovered plugin.
        /// We firstly check the cache for the operation claims for the given request key.
        /// If there is a valid cache entry, and it does contain the requested operation claim, then we start the plugin, and if need be update the cache value itself.
        /// If there is a valid cache entry, and it does NOT contain the requested operation claim, then we return a null.
        /// If there is no valid cache entry or an invalid one, we start the plugin as normally, return an active plugin even if the requested claim is not available, and write a cache entry.
        /// </summary>
        /// <param name="result">plugin discovery result</param>
        /// <param name="requestedOperationClaim">The requested operation claim</param>
        /// <param name="requestKey">plugin request key</param>
        /// <param name="packageSourceRepository">package source repository</param>
        /// <param name="serviceIndex">service index</param>
        /// <param name="cancellationToken">cancellation token</param>
        /// <returns>A plugin creation result, null if the requested plugin cannot handle the given operation claim</returns>
        private async Task <Tuple <bool, PluginCreationResult> > TryCreatePluginAsync(
            PluginDiscoveryResult result,
            OperationClaim requestedOperationClaim,
            PluginRequestKey requestKey,
            string packageSourceRepository,
            JObject serviceIndex,
            CancellationToken cancellationToken)
        {
            PluginCreationResult pluginCreationResult = null;
            var cacheEntry = new PluginCacheEntry(_pluginsCacheDirectory.Value, result.PluginFile.Path, requestKey.PackageSourceRepository);

            return(await ConcurrencyUtilities.ExecuteWithFileLockedAsync(
                       cacheEntry.CacheFileName,
                       action : async lockedToken =>
            {
                if (cacheEntry.OperationClaims == null || cacheEntry.OperationClaims.Contains(requestedOperationClaim))
                {
                    if (result.PluginFile.State.Value == PluginFileState.Valid)
                    {
                        var plugin = await _pluginFactory.GetOrCreateAsync(
                            result.PluginFile.Path,
                            PluginConstants.PluginArguments,
                            new RequestHandlers(),
                            _connectionOptions,
                            cancellationToken);

                        var utilities = await PerformOneTimePluginInitializationAsync(plugin, cancellationToken);

                        // We still make the GetOperationClaims call even if we have the operation claims cached. This is a way to self-update the cache.
                        var operationClaims = await _pluginOperationClaims.GetOrAdd(
                            requestKey,
                            key => new Lazy <Task <IReadOnlyList <OperationClaim> > >(() =>
                                                                                      GetPluginOperationClaimsAsync(
                                                                                          plugin,
                                                                                          packageSourceRepository,
                                                                                          serviceIndex,
                                                                                          cancellationToken))).Value;

                        if (!EqualityUtility.SequenceEqualWithNullCheck(operationClaims, cacheEntry.OperationClaims))
                        {
                            cacheEntry.OperationClaims = operationClaims;
                            await cacheEntry.UpdateCacheFileAsync();
                        }

                        pluginCreationResult = new PluginCreationResult(
                            plugin,
                            utilities.Value,
                            operationClaims);
                    }
                    else
                    {
                        pluginCreationResult = new PluginCreationResult(result.Message);
                    }
                }
                return new Tuple <bool, PluginCreationResult>(pluginCreationResult != null, pluginCreationResult);
            },
                       token : cancellationToken
                       ));
        }
コード例 #2
0
ファイル: PluginManager.cs プロジェクト: anhphan/NuGet.Client
        private async Task <PluginCreationResult> CreatePluginAsync(PluginDiscoveryResult result, PluginRequestKey requestKey, string packageSourceRepository, JObject serviceIndex, CancellationToken cancellationToken)
        {
            PluginCreationResult pluginCreationResult = null;

            if (result.PluginFile.State.Value == PluginFileState.Valid)
            {
                var plugin = await _pluginFactory.GetOrCreateAsync(
                    result.PluginFile.Path,
                    PluginConstants.PluginArguments,
                    new RequestHandlers(),
                    _connectionOptions,
                    cancellationToken);

                var utilities = await PerformOneTimePluginInitializationAsync(plugin, cancellationToken);

                var lazyOperationClaims = _pluginOperationClaims.GetOrAdd(
                    requestKey,
                    key => new Lazy <Task <IReadOnlyList <OperationClaim> > >(() =>
                                                                              GetPluginOperationClaimsAsync(
                                                                                  plugin,
                                                                                  packageSourceRepository,
                                                                                  serviceIndex,
                                                                                  cancellationToken)));

                await lazyOperationClaims.Value;

                pluginCreationResult = new PluginCreationResult(
                    plugin,
                    utilities.Value,
                    lazyOperationClaims.Value.Result);
            }
            else
            {
                pluginCreationResult = new PluginCreationResult(result.Message);
            }

            return(pluginCreationResult);
        }
コード例 #3
0
        /// <summary>
        /// Creates a plugin from the discovered plugin.
        /// We firstly check the cache for the operation claims for the given request key.
        /// If there is a valid cache entry, and it does contain the requested operation claim, then we start the plugin, and if need be update the cache value itself.
        /// If there is a valid cache entry, and it does NOT contain the requested operation claim, then we return a null.
        /// If there is no valid cache entry or an invalid one, we start the plugin as normally, return an active plugin even if the requested claim is not available, and write a cache entry.
        /// </summary>
        /// <param name="result">plugin discovery result</param>
        /// <param name="requestedOperationClaim">The requested operation claim</param>
        /// <param name="requestKey">plugin request key</param>
        /// <param name="packageSourceRepository">package source repository</param>
        /// <param name="serviceIndex">service index</param>
        /// <param name="cancellationToken">cancellation token</param>
        /// <returns>A plugin creation result, null if the requested plugin cannot handle the given operation claim</returns>
        private async Task <Tuple <bool, PluginCreationResult> > TryCreatePluginAsync(
            PluginDiscoveryResult result,
            OperationClaim requestedOperationClaim,
            PluginRequestKey requestKey,
            string packageSourceRepository,
            JObject serviceIndex,
            CancellationToken cancellationToken)
        {
            // This is a non cancellable task.
            // We should only honor cancellation requests we can recover from.
            // Once we have reached this part of the code, we do the plugin initialization
            // handshake, operation claims, and shut down set up.
            // If either one of these tasks fails then the plugin itself is not usable for the rest of the process.
            // We could consider handling each of this operations more cleverly,
            // but simplicity and readability is prioritized
            cancellationToken = CancellationToken.None;
            PluginCreationResult pluginCreationResult = null;
            var cacheEntry = new PluginCacheEntry(_pluginsCacheDirectoryPath.Value, result.PluginFile.Path, requestKey.PackageSourceRepository);

            ConcurrencyUtilities.ExecuteWithFileLocked(cacheEntry.CacheFileName, cacheEntry.LoadFromFile);

            if (cacheEntry.OperationClaims == null || cacheEntry.OperationClaims.Contains(requestedOperationClaim))
            {
                try
                {
                    if (result.PluginFile.State.Value == PluginFileState.Valid)
                    {
                        var plugin = await _pluginFactory.GetOrCreateAsync(
                            result.PluginFile.Path,
                            PluginConstants.PluginArguments,
                            new RequestHandlers(),
                            _connectionOptions,
                            cancellationToken);

                        var utilities = await PerformOneTimePluginInitializationAsync(plugin, cancellationToken);

                        // We still make the GetOperationClaims call even if we have the operation claims cached. This is a way to self-update the cache.
                        var operationClaims = await _pluginOperationClaims.GetOrAdd(
                            requestKey,
                            key => new Lazy <Task <IReadOnlyList <OperationClaim> > >(() =>
                                                                                      GetPluginOperationClaimsAsync(
                                                                                          plugin,
                                                                                          packageSourceRepository,
                                                                                          serviceIndex,
                                                                                          cancellationToken))).Value;

                        if (!EqualityUtility.SequenceEqualWithNullCheck(operationClaims, cacheEntry.OperationClaims))
                        {
                            cacheEntry.OperationClaims = operationClaims;

                            await utilities.Value.DoOncePerPluginLifetimeAsync(
                                nameof(PluginCacheEntry),
                                () => ConcurrencyUtilities.ExecuteWithFileLockedAsync(
                                    cacheEntry.CacheFileName,
                                    action: async lockedToken =>
                            {
                                await cacheEntry.UpdateCacheFileAsync();

                                return(Task.FromResult <object>(null));
                            },
                                    token: cancellationToken),
                                cancellationToken);
                        }

                        pluginCreationResult = new PluginCreationResult(
                            plugin,
                            utilities.Value,
                            operationClaims);
                    }
                    else
                    {
                        pluginCreationResult = new PluginCreationResult(result.Message);
                    }
                }
                catch (Exception e)
                {
                    pluginCreationResult = new PluginCreationResult(
                        string.Format(CultureInfo.CurrentCulture,
                                      Strings.Plugin_ProblemStartingPlugin,
                                      result.PluginFile.Path,
                                      e.Message),
                        e);
                }
            }

            return(new Tuple <bool, PluginCreationResult>(pluginCreationResult != null, pluginCreationResult));
        }