Headless CMS and Content Managment Hub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

84 lines
2.4 KiB

// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using NodaTime;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Orleans;
namespace Squidex.Domain.Apps.Entities.Comments
{
public sealed class WatchingGrain : GrainBase, IWatchingGrain
{
private static readonly Duration Timeout = Duration.FromMinutes(1);
private readonly Dictionary<string, Dictionary<string, Instant>> users = new Dictionary<string, Dictionary<string, Instant>>();
private readonly IClock clock;
public WatchingGrain(IClock clock)
{
this.clock = clock;
}
public override Task OnActivateAsync()
{
var time = TimeSpan.FromSeconds(30);
RegisterTimer(x =>
{
Cleanup();
return Task.CompletedTask;
}, null, time, time);
return Task.CompletedTask;
}
public Task<string[]> GetWatchingUsersAsync(string resource, string userId)
{
Guard.NotNullOrEmpty(resource);
Guard.NotNullOrEmpty(userId);
var usersByResource = users.GetOrAddNew(resource);
usersByResource[userId] = clock.GetCurrentInstant();
return Task.FromResult(usersByResource.Keys.ToArray());
}
public void Cleanup()
{
if (users.Count == 0)
{
return;
}
var now = clock.GetCurrentInstant();
foreach (var (resource, usersByResource) in users.ToList())
{
foreach (var (userId, lastSeen) in usersByResource.ToList())
{
var timeSinceLastSeen = now - lastSeen;
if (timeSinceLastSeen > Timeout)
{
usersByResource.Remove(userId);
}
}
if (usersByResource.Count == 0)
{
users.Remove(resource);
}
}
if (users.Count == 0)
{
TryDeactivateOnIdle();
}
}
}
}