Exemplo n.º 1
0
        private void ProcessRequests(PackageProvider[] providers)
        {
            if (providers == null || providers.Length == 0)
            {
                return;
            }

            var requests = providers.SelectMany(pv => {
                Verbose(Resources.Messages.SelectedProviders, pv.ProviderName);
                // for a given provider, if we get an error, we want just that provider to stop.
                var host = GetProviderSpecificOption(pv);

                var a = _uris.Select(uri => new {
                    query = new List<string> {
                            uri.AbsolutePath
                        },
                    provider = pv,
                    packages = pv.FindPackageByUri(uri, host).CancelWhen(CancellationEvent.Token)
                });

                var b = _files.Keys.Where(file => pv.IsSupportedFile(_files[file].Item2)).Select(file => new {
                    query = _files[file].Item1,
                    provider = pv,
                    packages = pv.FindPackageByFile(file, host)
                });

                var c = _names.Select(name => new {
                    query = new List<string> {
                            name
                        },
                    provider = pv,
                    packages = pv.FindPackage(name, RequiredVersion, MinimumVersion, MaximumVersion, host)
                });

                return a.Concat(b).Concat(c);
            }).ToArray();

            Debug("Calling SearchForPackages After Select {0}", requests.Length);

            if (AllVersions || !SpecifiedMinimumOrMaximum) {
                // the user asked for every version or they didn't specify any version ranges
                // either way, that means that we can just return everything that we're finding.

                while (WaitForActivity(requests.Select(each => each.packages))) {

                    // keep processing while any of the the queries is still going.

                    foreach (var result in requests.Where(each => each.packages.HasData)) {
                        // look only at requests that have data waiting.

                        foreach (var package in result.packages.GetConsumingEnumerable()) {
                            // process the results for that set.
                            // check if the package is a provider package. If so we need to filter on the packages for the providers.
                            if (EnsurePackageIsProvider(package)) {
                                ProcessPackage(result.provider, result.query, package);
                            }
                        }
                    }

                    requests = requests.FilterWithFinalizer(each => each.packages.IsConsumed, each => each.packages.Dispose()).ToArray();
                }

            } else {
                // now this is where it gets a bit funny.
                // the user specified a min or max
                // and so we have to only return the highest one in the set for a given package.

                while (WaitForActivity(requests.Select(each => each.packages))) {
                    // keep processing while any of the the queries is still going.
                    foreach (var perProvider in requests.GroupBy(each => each.provider)) {
                        foreach (var perQuery in perProvider.GroupBy(each => each.query)) {
                            if (perQuery.All(each => each.packages.IsCompleted && !each.packages.IsConsumed)) {
                                foreach (var pkg in from p in perQuery.SelectMany(each => each.packages.GetConsumingEnumerable())
                                                    group p by new {
                                                        p.Name,
                                                        p.Source
                                                    }
                                                        // for a given name
                                                        into grouping
                                                        // get the latest version only
                                                        select grouping.OrderByDescending(pp => pp, SoftwareIdentityVersionComparer.Instance).First()) {

                                    if (EnsurePackageIsProvider(pkg)) {
                                        ProcessPackage(perProvider.Key, perQuery.Key, pkg);
                                    }
                                }
                            }
                        }
                    }
                    // filter out whatever we're done with.
                    requests = requests.FilterWithFinalizer(each => each.packages.IsConsumed, each => each.packages.Dispose()).ToArray();
                }
            }

            // dispose of any requests that didn't get cleaned up earlier.
            foreach (var i in requests) {
                i.packages.Dispose();
            }
        }