Browse Source

Don't cache grain.

pull/585/head
Sebastian 5 years ago
parent
commit
a795a717d4
  1. 11
      backend/src/Squidex.Domain.Apps.Entities/Apps/Diagnostics/OrleansAppsHealthCheck.cs
  2. 12
      backend/src/Squidex.Domain.Apps.Entities/Apps/Plans/UsageGate.cs
  3. 9
      backend/src/Squidex.Domain.Apps.Entities/Comments/CommentsCommandMiddleware.cs
  4. 15
      backend/src/Squidex.Domain.Apps.Entities/Rules/UsageTracking/UsageTrackerCommandMiddleware.cs
  5. 54
      backend/tests/Squidex.Infrastructure.Tests/Orleans/AsyncLocalTests.cs

11
backend/src/Squidex.Domain.Apps.Entities/Apps/Diagnostics/OrleansAppsHealthCheck.cs

@ -17,20 +17,25 @@ namespace Squidex.Domain.Apps.Entities.Apps.Diagnostics
{
public sealed class OrleansAppsHealthCheck : IHealthCheck
{
private readonly IAppsByNameIndexGrain index;
private readonly IGrainFactory grainFactory;
public OrleansAppsHealthCheck(IGrainFactory grainFactory)
{
Guard.NotNull(grainFactory, nameof(grainFactory));
index = grainFactory.GetGrain<IAppsByNameIndexGrain>(SingleGrain.Id);
this.grainFactory = grainFactory;
}
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
await index.CountAsync();
await GetGrain().CountAsync();
return HealthCheckResult.Healthy("Orleans must establish communication.");
}
private IAppsByNameIndexGrain GetGrain()
{
return grainFactory.GetGrain<IAppsByNameIndexGrain>(SingleGrain.Id);
}
}
}

12
backend/src/Squidex.Domain.Apps.Entities/Apps/Plans/UsageGate.cs

@ -24,7 +24,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Plans
private readonly MemoryCache memoryCache = new MemoryCache(Options.Create(new MemoryCacheOptions()));
private readonly IAppPlansProvider appPlansProvider;
private readonly IApiUsageTracker apiUsageTracker;
private readonly IUsageNotifierGrain usageLimitNotifier;
private readonly IGrainFactory grainFactory;
public UsageGate(IAppPlansProvider appPlansProvider, IApiUsageTracker apiUsageTracker, IGrainFactory grainFactory)
{
@ -34,8 +34,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Plans
this.appPlansProvider = appPlansProvider;
this.apiUsageTracker = apiUsageTracker;
usageLimitNotifier = grainFactory.GetGrain<IUsageNotifierGrain>(SingleGrain.Id);
this.grainFactory = grainFactory;
}
public virtual async Task<bool> IsBlockedAsync(IAppEntity app, string? clientId, DateTime today)
@ -72,7 +71,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Plans
Users = users
};
usageLimitNotifier.NotifyAsync(notification).Forget();
GetGrain().NotifyAsync(notification).Forget();
TrackNotified(appId);
}
@ -83,6 +82,11 @@ namespace Squidex.Domain.Apps.Entities.Apps.Plans
return isBlocked;
}
private IUsageNotifierGrain GetGrain()
{
return grainFactory.GetGrain<IUsageNotifierGrain>(SingleGrain.Id);
}
private bool HasNotifiedBefore(Guid appId)
{
return memoryCache.Get<bool>(appId);

9
backend/src/Squidex.Domain.Apps.Entities/Comments/CommentsCommandMiddleware.cs

@ -52,13 +52,16 @@ namespace Squidex.Domain.Apps.Entities.Comments
private async Task ExecuteCommandAsync(CommandContext context, CommentsCommand commentsCommand)
{
var grain = grainFactory.GetGrain<ICommentsGrain>(commentsCommand.CommentsId);
var result = await grain.ExecuteAsync(commentsCommand.AsJ());
var result = await GetGrain(commentsCommand).ExecuteAsync(commentsCommand.AsJ());
context.Complete(result.Value);
}
private ICommentsGrain GetGrain(CommentsCommand commentsCommand)
{
return grainFactory.GetGrain<ICommentsGrain>(commentsCommand.CommentsId);
}
private static bool IsMention(CreateComment createComment)
{
return createComment.IsMention;

15
backend/src/Squidex.Domain.Apps.Entities/Rules/UsageTracking/UsageTrackerCommandMiddleware.cs

@ -17,13 +17,13 @@ namespace Squidex.Domain.Apps.Entities.Rules.UsageTracking
{
public sealed class UsageTrackerCommandMiddleware : ICommandMiddleware
{
private readonly IUsageTrackerGrain usageTrackerGrain;
private readonly IGrainFactory grainFactory;
public UsageTrackerCommandMiddleware(IGrainFactory grainFactory)
{
Guard.NotNull(grainFactory, nameof(grainFactory));
usageTrackerGrain = grainFactory.GetGrain<IUsageTrackerGrain>(SingleGrain.Id);
this.grainFactory = grainFactory;
}
public async Task HandleAsync(CommandContext context, NextDelegate next)
@ -31,13 +31,13 @@ namespace Squidex.Domain.Apps.Entities.Rules.UsageTracking
switch (context.Command)
{
case DeleteRule deleteRule:
await usageTrackerGrain.RemoveTargetAsync(deleteRule.RuleId);
await GetGrain().RemoveTargetAsync(deleteRule.RuleId);
break;
case CreateRule createRule:
{
if (createRule.Trigger is UsageTrigger usage)
{
await usageTrackerGrain.AddTargetAsync(createRule.RuleId, createRule.AppId, usage.Limit, usage.NumDays);
await GetGrain().AddTargetAsync(createRule.RuleId, createRule.AppId, usage.Limit, usage.NumDays);
}
break;
@ -47,7 +47,7 @@ namespace Squidex.Domain.Apps.Entities.Rules.UsageTracking
{
if (ruleUpdated.Trigger is UsageTrigger usage)
{
await usageTrackerGrain.UpdateTargetAsync(ruleUpdated.RuleId, usage.Limit, usage.NumDays);
await GetGrain().UpdateTargetAsync(ruleUpdated.RuleId, usage.Limit, usage.NumDays);
}
break;
@ -56,5 +56,10 @@ namespace Squidex.Domain.Apps.Entities.Rules.UsageTracking
await next(context);
}
private IUsageTrackerGrain GetGrain()
{
return grainFactory.GetGrain<IUsageTrackerGrain>(SingleGrain.Id);
}
}
}

54
backend/tests/Squidex.Infrastructure.Tests/Orleans/AsyncLocalTests.cs

@ -0,0 +1,54 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Threading;
using System.Threading.Tasks;
using Orleans;
using Orleans.TestingHost;
using Xunit;
namespace Squidex.Infrastructure.Orleans
{
[Trait("Category", "Dependencies")]
public class AsyncLocalTests
{
public interface IAsyncLocalGrain : IGrainWithStringKey
{
public Task<int> GetValueAsync();
}
public class AsyncLocalGrain : Grain, IAsyncLocalGrain
{
private readonly AsyncLocal<int> temp = new AsyncLocal<int>();
public Task<int> GetValueAsync()
{
temp.Value++;
return Task.FromResult(temp.Value);
}
}
[Fact]
public async Task Should_use_async_local()
{
var cluster =
new TestClusterBuilder(1)
.Build();
await cluster.DeployAsync();
var grain = cluster.GrainFactory.GetGrain<IAsyncLocalGrain>(SingleGrain.Id);
var result1 = await grain.GetValueAsync();
var result2 = await grain.GetValueAsync();
Assert.Equal(1, result1);
Assert.Equal(1, result2);
}
}
}
Loading…
Cancel
Save