DocSpace-client/common/services/ASC.Feed.Aggregator/Service/FeedAggregatorService.cs

246 lines
9.5 KiB
C#
Raw Normal View History

namespace ASC.Feed.Aggregator.Service
2020-06-03 14:53:58 +00:00
{
2022-02-11 13:57:42 +00:00
[Singletone(Additional = typeof(FeedAggregatorServiceExtension))]
public class FeedAggregatorService : FeedBaseService
2020-06-03 14:53:58 +00:00
{
2022-02-11 13:57:42 +00:00
protected override string LoggerName { get; set; } = "ASC.Feed.Aggregator";
private readonly SignalrServiceClient _signalrServiceClient;
2020-06-03 14:53:58 +00:00
public FeedAggregatorService(
2022-01-21 08:26:25 +00:00
FeedSettings feedSettings,
2020-06-03 14:53:58 +00:00
IServiceProvider serviceProvider,
2020-08-14 10:56:15 +00:00
IOptionsMonitor<ILog> optionsMonitor,
SignalrServiceClient signalrServiceClient)
: base(feedSettings, serviceProvider, optionsMonitor)
2020-06-03 14:53:58 +00:00
{
_signalrServiceClient = signalrServiceClient;
2020-06-03 14:53:58 +00:00
}
public override Task StartAsync(CancellationToken cancellationToken)
2020-06-03 14:53:58 +00:00
{
Logger.Info("Feed Aggregator service running.");
2022-01-21 08:26:25 +00:00
var cfg = FeedSettings;
IsStopped = false;
2020-06-03 14:53:58 +00:00
Timer = new Timer(AggregateFeeds, cfg.AggregateInterval, TimeSpan.Zero, cfg.AggregatePeriod);
2020-06-03 14:53:58 +00:00
return Task.CompletedTask;
}
public override Task StopAsync(CancellationToken cancellationToken)
2020-06-03 14:53:58 +00:00
{
Logger.Info("Feed Aggregator service stopping.");
2020-06-03 14:53:58 +00:00
IsStopped = true;
2020-06-03 14:53:58 +00:00
Timer?.Change(Timeout.Infinite, 0);
2020-06-03 14:53:58 +00:00
return Task.CompletedTask;
}
private void AggregateFeeds(object interval)
{
if (!Monitor.TryEnter(LockObj))
{
return;
}
2020-06-03 14:53:58 +00:00
try
{
2022-01-21 08:26:25 +00:00
var cfg = FeedSettings;
2020-06-03 14:53:58 +00:00
using var scope = ServiceProvider.CreateScope();
2020-08-24 18:41:06 +00:00
var scopeClass = scope.ServiceProvider.GetService<FeedAggregatorServiceScope>();
2021-01-12 17:51:14 +00:00
var cache = scope.ServiceProvider.GetService<ICache>();
2020-09-07 12:01:15 +00:00
var (baseCommonLinkUtility, tenantManager, feedAggregateDataProvider, userManager, securityContext, authManager) = scopeClass;
2020-08-31 08:18:07 +00:00
baseCommonLinkUtility.Initialize(cfg.ServerRoot);
2020-06-03 14:53:58 +00:00
var start = DateTime.UtcNow;
Logger.DebugFormat("Start of collecting feeds...");
2020-06-03 14:53:58 +00:00
var unreadUsers = new Dictionary<int, Dictionary<Guid, int>>();
2021-07-22 08:56:52 +00:00
var modules = scope.ServiceProvider.GetService<IEnumerable<IFeedModule>>();
2020-06-03 14:53:58 +00:00
foreach (var module in modules)
{
var result = new List<FeedRow>();
2020-08-31 08:18:07 +00:00
var fromTime = feedAggregateDataProvider.GetLastTimeAggregate(module.GetType().Name);
2020-06-03 14:53:58 +00:00
if (fromTime == default) fromTime = DateTime.UtcNow.Subtract((TimeSpan)interval);
var toTime = DateTime.UtcNow;
var tenants = Attempt(10, () => module.GetTenantsWithFeeds(fromTime)).ToList();
Logger.DebugFormat("Find {1} tenants for module {0}.", module.GetType().Name, tenants.Count);
2020-06-03 14:53:58 +00:00
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
{
2020-08-31 08:18:07 +00:00
if (tenantManager.GetTenant(tenant) == null)
2020-06-03 14:53:58 +00:00
{
continue;
}
2020-10-12 19:39:23 +00:00
tenantManager.SetCurrentTenant(tenant);
2020-08-31 08:18:07 +00:00
var users = userManager.GetUsers();
2020-06-03 14:53:58 +00:00
var feeds = Attempt(10, () => module.GetFeeds(new FeedFilter(fromTime, toTime) { Tenant = tenant }).Where(r => r.Item1 != null).ToList());
Logger.DebugFormat("{0} feeds in {1} tenant.", feeds.Count, tenant);
2020-06-03 14:53:58 +00:00
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)
2020-06-03 14:53:58 +00:00
{
return;
}
2020-08-31 08:18:07 +00:00
if (!TryAuthenticate(securityContext, authManager, tenant1, u.ID))
2020-06-03 14:53:58 +00:00
{
continue;
}
module.VisibleFor(feedsRow, u.ID);
}
result.AddRange(feedsRow.Select(r => r.Item1));
}
catch (Exception ex)
{
Logger.ErrorFormat("Tenant: {0}, {1}", tenant, ex);
2020-06-03 14:53:58 +00:00
}
}
2020-08-31 08:18:07 +00:00
feedAggregateDataProvider.SaveFeeds(result, module.GetType().Name, toTime);
2020-06-03 14:53:58 +00:00
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);
2020-06-03 14:53:58 +00:00
Logger.DebugFormat("Time of collecting news: {0}", DateTime.UtcNow - start);
2020-06-03 14:53:58 +00:00
}
catch (Exception ex)
{
Logger.Error(ex);
2020-06-03 14:53:58 +00:00
}
finally
{
Monitor.Exit(LockObj);
2020-06-03 14:53:58 +00:00
}
}
private static T Attempt<T>(int count, Func<T> action)
{
var counter = 0;
while (true)
{
try
{
return action();
}
catch
{
if (count < ++counter)
{
throw;
}
}
}
}
private static bool TryAuthenticate(SecurityContext securityContext, AuthManager authManager, int tenantId, Guid userid)
{
try
{
2021-08-18 14:04:16 +00:00
securityContext.AuthenticateMeWithoutCookie(authManager.GetAccountByID(tenantId, userid));
2020-06-03 14:53:58 +00:00
return true;
}
catch
{
return false;
}
}
2020-08-24 18:41:06 +00:00
}
2020-07-29 21:57:58 +00:00
2020-10-19 15:53:15 +00:00
[Scope]
2020-08-24 18:41:06 +00:00
public class FeedAggregatorServiceScope
2020-10-12 16:23:15 +00:00
{
private readonly BaseCommonLinkUtility _baseCommonLinkUtility;
private readonly TenantManager _tenantManager;
private readonly FeedAggregateDataProvider _feedAggregateDataProvider;
private readonly UserManager _userManager;
private readonly SecurityContext _securityContext;
private readonly AuthManager _authManager;
2020-10-12 16:23:15 +00:00
public FeedAggregatorServiceScope(BaseCommonLinkUtility baseCommonLinkUtility,
TenantManager tenantManager,
FeedAggregateDataProvider feedAggregateDataProvider,
UserManager userManager,
SecurityContext securityContext,
AuthManager authManager)
2020-07-29 21:57:58 +00:00
{
_baseCommonLinkUtility = baseCommonLinkUtility;
_tenantManager = tenantManager;
_feedAggregateDataProvider = feedAggregateDataProvider;
_userManager = userManager;
_securityContext = securityContext;
_authManager = authManager;
2020-10-12 16:23:15 +00:00
}
2020-08-31 08:18:07 +00:00
public void Deconstruct(out BaseCommonLinkUtility baseCommonLinkUtility,
out TenantManager tenantManager,
2020-10-12 16:23:15 +00:00
out FeedAggregateDataProvider feedAggregateDataProvider,
out UserManager userManager,
out SecurityContext securityContext,
2020-08-31 08:18:07 +00:00
out AuthManager authManager)
{
baseCommonLinkUtility = _baseCommonLinkUtility;
tenantManager = _tenantManager;
feedAggregateDataProvider = _feedAggregateDataProvider;
userManager = _userManager;
securityContext = _securityContext;
authManager = _authManager;
2020-07-29 21:57:58 +00:00
}
2020-08-31 08:18:07 +00:00
}
2022-01-21 10:47:56 +00:00
public static class FeedAggregatorServiceExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<FeedAggregatorServiceScope>();
}
}
2020-06-03 14:53:58 +00:00
}