Beispiel #1
0
        public Task StartAsync(CancellationToken cancellationToken)
        {
            var cfg = FeedSettings.GetInstance(Configuration);

            isStopped = false;

            aggregateTimer = new Timer(AggregateFeeds, cfg.AggregateInterval, TimeSpan.Zero, cfg.AggregatePeriod);
            removeTimer    = new Timer(RemoveFeeds, cfg.AggregateInterval, cfg.RemovePeriod, cfg.RemovePeriod);

            return(Task.CompletedTask);
        }
Beispiel #2
0
        private void AggregateFeeds(object interval)
        {
            if (!Monitor.TryEnter(aggregateLock))
            {
                return;
            }

            try
            {
                var cfg = FeedSettings.GetInstance(Configuration);
                using var scope = ServiceProvider.CreateScope();
                var scopeClass = scope.ServiceProvider.GetService <FeedAggregatorServiceScope>();
                var cache      = scope.ServiceProvider.GetService <ICache>();
                var(baseCommonLinkUtility, tenantManager, feedAggregateDataProvider, userManager, securityContext, authManager) = scopeClass;
                baseCommonLinkUtility.Initialize(cfg.ServerRoot);

                var start = DateTime.UtcNow;
                Log.DebugFormat("Start of collecting feeds...");

                var unreadUsers = new Dictionary <int, Dictionary <Guid, int> >();
                var modules     = scope.ServiceProvider.GetService <IEnumerable <IFeedModule> >();

                foreach (var module in modules)
                {
                    var result   = new List <FeedRow>();
                    var fromTime = feedAggregateDataProvider.GetLastTimeAggregate(module.GetType().Name);
                    if (fromTime == default)
                    {
                        fromTime = DateTime.UtcNow.Subtract((TimeSpan)interval);
                    }
                    var toTime = DateTime.UtcNow;

                    var tenants = Attempt(10, () => module.GetTenantsWithFeeds(fromTime)).ToList();
                    Log.DebugFormat("Find {1} tenants for module {0}.", module.GetType().Name, tenants.Count());

                    foreach (var tenant in tenants)
                    {
                        // Warning! There is hack here!
                        // clearing the cache to get the correct acl
                        cache.Remove("acl" + tenant);
                        cache.Remove("/webitemsecurity/" + tenant);
                        //cache.Remove(string.Format("sub/{0}/{1}/{2}", tenant, "6045b68c-2c2e-42db-9e53-c272e814c4ad", NotifyConstants.Event_NewCommentForMessage.ID));

                        try
                        {
                            if (tenantManager.GetTenant(tenant) == null)
                            {
                                continue;
                            }

                            tenantManager.SetCurrentTenant(tenant);
                            var users = userManager.GetUsers();

                            var feeds = Attempt(10, () => module.GetFeeds(new FeedFilter(fromTime, toTime)
                            {
                                Tenant = tenant
                            }).Where(r => r.Item1 != null).ToList());
                            Log.DebugFormat("{0} feeds in {1} tenant.", feeds.Count, tenant);

                            var tenant1  = tenant;
                            var module1  = module;
                            var feedsRow = feeds
                                           .Select(tuple => new Tuple <FeedRow, object>(new FeedRow(tuple.Item1)
                            {
                                Tenant    = tenant1,
                                ProductId = module1.Product
                            }, tuple.Item2))
                                           .ToList();

                            foreach (var u in users)
                            {
                                if (isStopped)
                                {
                                    return;
                                }
                                if (!TryAuthenticate(securityContext, authManager, tenant1, u.ID))
                                {
                                    continue;
                                }

                                module.VisibleFor(feedsRow, u.ID);
                            }

                            result.AddRange(feedsRow.Select(r => r.Item1));
                        }
                        catch (Exception ex)
                        {
                            Log.ErrorFormat("Tenant: {0}, {1}", tenant, ex);
                        }
                    }

                    feedAggregateDataProvider.SaveFeeds(result, module.GetType().Name, toTime);

                    foreach (var res in result)
                    {
                        foreach (var userGuid in res.Users.Where(userGuid => !userGuid.Equals(res.ModifiedById)))
                        {
                            if (!unreadUsers.TryGetValue(res.Tenant, out var dictionary))
                            {
                                dictionary = new Dictionary <Guid, int>();
                            }
                            if (dictionary.ContainsKey(userGuid))
                            {
                                ++dictionary[userGuid];
                            }
                            else
                            {
                                dictionary.Add(userGuid, 1);
                            }

                            unreadUsers[res.Tenant] = dictionary;
                        }
                    }
                }

                SignalrServiceClient.SendUnreadUsers(unreadUsers);

                Log.DebugFormat("Time of collecting news: {0}", DateTime.UtcNow - start);
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
            finally
            {
                Monitor.Exit(aggregateLock);
            }
        }