Пример #1
0
        private static QueryResults GetMultiSiteResults(ParsedQuery parsedQuery, User currentUser, AsyncQueryRunner.AsyncResult result = null)
        {
            var sites = Current.DB.Sites.All();

            if (parsedQuery.TargetSites == TargetSites.AllNonMetaSites)
            {
                sites = sites.Where(s => !s.Url.Contains("meta.")).ToList();
            }
            else if (parsedQuery.TargetSites == TargetSites.AllMetaSites)
            {
                sites = sites.Where(s => s.Url.Contains("meta.")).ToList();
            }

            var firstSite = sites.First();
            var results   = QueryRunner.GetSingleSiteResults(parsedQuery, firstSite, currentUser, result);

            if (results.ResultSets.First().Columns.Where(c => c.Name == "Pivot").Any())
            {
                foreach (var info in results.ResultSets.First().Columns)
                {
                    if (info.Name == "Pivot")
                    {
                        info.Name = firstSite.Name + " Pivot";
                        break;
                    }
                }

                foreach (var s in sites.Skip(1))
                {
                    try
                    {
                        var tmp = QueryRunner.GetSingleSiteResults(parsedQuery, s, currentUser);
                        results.ExecutionTime += tmp.ExecutionTime;
                        MergePivot(s, results, tmp);
                    }
                    catch (Exception)
                    {
                        // don't blow up here ... just skip the site.
                    }
                }
            }
            else
            {
                results.ResultSets[0].Columns.Add(new ResultColumnInfo {
                    Name = "Site Name", Type = ResultColumnType.Site
                });
                foreach (var row in results.ResultSets[0].Rows)
                {
                    row.Add(sites.First().SiteInfo);
                }

                foreach (var s in sites.Skip(1))
                {
                    if (result != null && result.Cancelled)
                    {
                        break;
                    }

                    try
                    {
                        var tmp = QueryRunner.GetSingleSiteResults(parsedQuery, s, currentUser, result);

                        foreach (var row in tmp.ResultSets[0].Rows)
                        {
                            row.Add(s.SiteInfo);
                            results.ResultSets[0].Rows.Add(row);
                        }

                        results.ExecutionTime += tmp.ExecutionTime;
                        results.Messages      += "\n" + tmp.Messages;
                    }
                    catch (Exception)
                    {
                        // don't blow up ... just skip the site
                    }
                }
            }

            results.TargetSites = parsedQuery.TargetSites;

            return(results);
        }
        public static AsyncResult Execute(ParsedQuery query, User user, Site site, QueryContextData context)
        {
            string userTag = user.IsAnonymous ? user.IPAddress : user.Id.ToString();

            List <Task> activeTasks;

            running.TryGetValue(userTag, out activeTasks);
            if (activeTasks != null)
            {
                lock (activeTasks)
                {
                    if (activeTasks.Where(t => !t.IsCompleted).Count() >= AppSettings.ConcurrentQueries)
                    {
                        throw new ApplicationException("Too many queries are running, you may only run " + AppSettings.ConcurrentQueries + " queries at a time");
                    }
                }
            }
            else
            {
                running.TryAdd(userTag, new List <Task>());
                activeTasks = running[userTag];
            }

            AsyncResult result = new AsyncResult
            {
                JobId            = Guid.NewGuid(),
                State            = AsyncState.Pending,
                ParsedQuery      = query,
                Site             = site,
                LastPoll         = DateTime.UtcNow,
                QueryContextData = context
            };

            Task task = new Task(() =>
            {
                try
                {
                    result.QueryResults = QueryRunner.GetResults(query, site, user, result);

                    if (result.State == AsyncState.Pending)
                    {
                        result.State = AsyncState.Success;
                    }
                }
                catch (Exception e)
                {
                    result.Exception = e;
                    result.State     = AsyncState.Failure;
                }
            });

            task.ContinueWith(ignore => {
                result.CompletionDate = DateTime.UtcNow;

                lock (activeTasks)
                {
                    activeTasks.RemoveAll(t => t.IsCompleted);
                }
            });

            result.Task = task;

            jobs.TryAdd(result.JobId, result);
            task.Start();
            lock (activeTasks)
            {
                activeTasks.Add(task);
            }

            // give it some time to get results ...
            System.Threading.Thread.Sleep(50);

            return(result);
        }