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 public sealed class OrleansAppsHealthCheck : IHealthCheck
{ {
private readonly IAppsByNameIndexGrain index; private readonly IGrainFactory grainFactory;
public OrleansAppsHealthCheck(IGrainFactory grainFactory) public OrleansAppsHealthCheck(IGrainFactory grainFactory)
{ {
Guard.NotNull(grainFactory, nameof(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) public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{ {
await index.CountAsync(); await GetGrain().CountAsync();
return HealthCheckResult.Healthy("Orleans must establish communication."); 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 MemoryCache memoryCache = new MemoryCache(Options.Create(new MemoryCacheOptions()));
private readonly IAppPlansProvider appPlansProvider; private readonly IAppPlansProvider appPlansProvider;
private readonly IApiUsageTracker apiUsageTracker; private readonly IApiUsageTracker apiUsageTracker;
private readonly IUsageNotifierGrain usageLimitNotifier; private readonly IGrainFactory grainFactory;
public UsageGate(IAppPlansProvider appPlansProvider, IApiUsageTracker apiUsageTracker, 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.appPlansProvider = appPlansProvider;
this.apiUsageTracker = apiUsageTracker; this.apiUsageTracker = apiUsageTracker;
this.grainFactory = grainFactory;
usageLimitNotifier = grainFactory.GetGrain<IUsageNotifierGrain>(SingleGrain.Id);
} }
public virtual async Task<bool> IsBlockedAsync(IAppEntity app, string? clientId, DateTime today) 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 Users = users
}; };
usageLimitNotifier.NotifyAsync(notification).Forget(); GetGrain().NotifyAsync(notification).Forget();
TrackNotified(appId); TrackNotified(appId);
} }
@ -83,6 +82,11 @@ namespace Squidex.Domain.Apps.Entities.Apps.Plans
return isBlocked; return isBlocked;
} }
private IUsageNotifierGrain GetGrain()
{
return grainFactory.GetGrain<IUsageNotifierGrain>(SingleGrain.Id);
}
private bool HasNotifiedBefore(Guid appId) private bool HasNotifiedBefore(Guid appId)
{ {
return memoryCache.Get<bool>(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) private async Task ExecuteCommandAsync(CommandContext context, CommentsCommand commentsCommand)
{ {
var grain = grainFactory.GetGrain<ICommentsGrain>(commentsCommand.CommentsId); var result = await GetGrain(commentsCommand).ExecuteAsync(commentsCommand.AsJ());
var result = await grain.ExecuteAsync(commentsCommand.AsJ());
context.Complete(result.Value); context.Complete(result.Value);
} }
private ICommentsGrain GetGrain(CommentsCommand commentsCommand)
{
return grainFactory.GetGrain<ICommentsGrain>(commentsCommand.CommentsId);
}
private static bool IsMention(CreateComment createComment) private static bool IsMention(CreateComment createComment)
{ {
return createComment.IsMention; 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 public sealed class UsageTrackerCommandMiddleware : ICommandMiddleware
{ {
private readonly IUsageTrackerGrain usageTrackerGrain; private readonly IGrainFactory grainFactory;
public UsageTrackerCommandMiddleware(IGrainFactory grainFactory) public UsageTrackerCommandMiddleware(IGrainFactory grainFactory)
{ {
Guard.NotNull(grainFactory, nameof(grainFactory)); Guard.NotNull(grainFactory, nameof(grainFactory));
usageTrackerGrain = grainFactory.GetGrain<IUsageTrackerGrain>(SingleGrain.Id); this.grainFactory = grainFactory;
} }
public async Task HandleAsync(CommandContext context, NextDelegate next) public async Task HandleAsync(CommandContext context, NextDelegate next)
@ -31,13 +31,13 @@ namespace Squidex.Domain.Apps.Entities.Rules.UsageTracking
switch (context.Command) switch (context.Command)
{ {
case DeleteRule deleteRule: case DeleteRule deleteRule:
await usageTrackerGrain.RemoveTargetAsync(deleteRule.RuleId); await GetGrain().RemoveTargetAsync(deleteRule.RuleId);
break; break;
case CreateRule createRule: case CreateRule createRule:
{ {
if (createRule.Trigger is UsageTrigger usage) 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; break;
@ -47,7 +47,7 @@ namespace Squidex.Domain.Apps.Entities.Rules.UsageTracking
{ {
if (ruleUpdated.Trigger is UsageTrigger usage) 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; break;
@ -56,5 +56,10 @@ namespace Squidex.Domain.Apps.Entities.Rules.UsageTracking
await next(context); 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