Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion samples/ArtifactGAgent/ArtifactGAgent.Silo/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
.AddLogStorageBasedLogConsistencyProvider("LogStorage")
.UseLocalhostClustering()
.UseAevatar()
.ConfigureLogging(logging => logging.AddConsole());
.ConfigureLogging(logging => logging.SetMinimumLevel(LogLevel.Information).AddConsole());
})
.UseConsoleLifetime();

Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Aevatar.Core;
using Aevatar.Core.Abstractions;
using Microsoft.Extensions.Logging;

namespace PluginGAgent.Grains;

Expand Down
10 changes: 2 additions & 8 deletions samples/PluginGAgent/PluginGAgent.Grains/WorkerGAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,10 @@ namespace PluginGAgent.Grains;

[GenerateSerializer]

public class WorkerGAgentState : StateBase
{

}
public class WorkerGAgentState : StateBase;

[GenerateSerializer]
public class WorkerStateLogEvent : StateLogEventBase<WorkerStateLogEvent>
{

}
public class WorkerStateLogEvent : StateLogEventBase<WorkerStateLogEvent>;

[GAgent("worker", "pluginTest")]
public class WorkerGAgent : GAgentBase<WorkerGAgentState, WorkerStateLogEvent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using MongoDB.Driver;
using Orleans.Configuration;

namespace PluginGAgent.Silo.Extensions;

Expand All @@ -30,6 +31,11 @@ public static IHostBuilder UseOrleansConfiguration(this IHostBuilder hostBuilder
})
.AddMemoryStreams("Aevatar")
.UseAevatarPermissionManagement()
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "default";
options.ServiceId = "testServiceId";
})
.UseAevatar()
;
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,6 @@ public PluginGAgentTestHostedService(
public async Task StartAsync(CancellationToken cancellationToken)
{
await _application.InitializeAsync(_serviceProvider);
var tenantId = "test".ToGuid();
var pluginManager = _serviceProvider.GetRequiredService<IPluginGAgentManager>();
var plugins = await pluginManager.GetPluginAssembliesAsync(tenantId);
Console.WriteLine("Plugins:");
foreach (var plugin in plugins)
{
Console.WriteLine(plugin.FullName);
}
var permissionManager = _serviceProvider.GetRequiredService<IPermissionManager>();
var userId = "TestUser".ToGuid().ToString();
await permissionManager.SetAsync("DoSomething", "User", userId, true);
}

public Task StopAsync(CancellationToken cancellationToken)
Expand Down
11 changes: 7 additions & 4 deletions samples/PluginGAgent/PluginGAgent.Silo/PluginGAgentTestModule.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
using System.Reflection;
using Aevatar;
using Aevatar.Core.Abstractions;
using Aevatar.PermissionManagement;
using Microsoft.Extensions.DependencyInjection;
using Orleans.Serialization;
using Serilog;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement;
using Volo.Abp.PermissionManagement.MongoDB;

namespace PluginGAgent.Silo;

[DependsOn(
typeof(AbpAspNetCoreSerilogModule),
typeof(AbpAutofacModule),
typeof(AbpAutoMapperModule),
typeof(AevatarPermissionManagementModule)
// typeof(AevatarPermissionManagementModule),
typeof(AevatarModule)
)]
public class PluginGAgentTestModule : AbpModule
{
Expand All @@ -29,5 +28,9 @@ public override void ConfigureServices(ServiceConfigurationContext context)
true, writeToProviders: true);
context.Services.AddHttpClient();
context.Services.AddSingleton<IEventDispatcher, DefaultEventDispatcher>();
// Configure<PermissionManagementOptions>(options =>
// {
// options.IsDynamicPermissionStoreEnabled = true;
// });
}
}
6 changes: 4 additions & 2 deletions samples/PluginGAgent/PluginGAgent.Silo/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@
]
},
"Plugins": {
"TenantId": "cd6b8f09214673d3cade4e832627b4f6"
"TenantId": "cd6b8f09214673d3cade4e832627b4f6",
"ConnectionString": "mongodb://localhost:27017/AevatarDb"
},
"ConnectionStrings": {
"Default": "mongodb://localhost:27017/Aevatar"
"Default": "mongodb://localhost:27017/Aevatar",
"Orleans": "mongodb://localhost:27017/AevatarDb"
},
"Aevatar": {
"StreamNamespace": "Aevatar"
Expand Down
13 changes: 13 additions & 0 deletions src/Aevatar.Core.Abstractions/IStateAgent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Orleans.Concurrency;
using Orleans.Streams;

namespace Aevatar.Core.Abstractions;

Expand Down Expand Up @@ -79,6 +80,18 @@ public interface IGAgent : IGrainWithGuidKey
/// <param name="configuration"></param>
/// <returns></returns>
Task ConfigAsync(ConfigurationBase configuration);

/// <summary>
/// Get GAgentAsyncObserver
/// </summary>
/// <returns></returns>
Task<IAsyncObserver<EventWrapperBase>> GetGAgentAsyncObserverAsync();

/// <summary>
/// Resume subscription of parent's stream.
/// </summary>
/// <returns></returns>
Task ResumeSubscriptionAsync(IAsyncStream<EventWrapperBase> stream);
}

public interface IStateGAgent<TState> : IGAgent
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
namespace Aevatar.Core.Abstractions.Projections;

public interface IProjectionGrain<TState> : IGrainWithGuidKey
where TState : StateBase, new()
public interface IProjectionGrain : IGrainWithStringKey
{
Task ActivateAsync();
}
1 change: 1 addition & 0 deletions src/Aevatar.Core/AevatarGAgentConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ public static class AevatarGAgentConstants
public const string StateHandlerDefaultMethodName = "HandleStateAsync";
public const string ConfigDefaultMethodName = "PerformConfigAsync";
public const string ForwardEventMethodName = "ForwardEventAsync";
public const int EventDispatcherMaxBatchSize = 20;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find the use of this anywhere

}
10 changes: 4 additions & 6 deletions src/Aevatar.Core/GAgentBase.Publish.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ private async Task SendEventUpwardsAsync<T>(EventWrapper<T> eventWrapper) where

try
{
var stream = GetEventBaseStream(State.Parent.Value);
var stream = GetEventBaseStreamForOwn(State.Parent.Value);
await stream.OnNextAsync(eventWrapper);
}
catch (Exception ex)
Expand All @@ -102,7 +102,7 @@ private async Task SendEventToSelfAsync<T>(EventWrapper<T> eventWrapper) where T
$"{GrainId.ToString()} is sending event to self: {JsonConvert.SerializeObject(eventWrapper)}");
try
{
var streamOfThisGAgent = GetEventBaseStream(GrainId);
var streamOfThisGAgent = GetEventBaseStreamForOwn(GrainId);
await streamOfThisGAgent.OnNextAsync(eventWrapper);
}
catch (Exception ex)
Expand All @@ -124,10 +124,8 @@ private async Task SendEventDownwardsAsync<T>(EventWrapper<T> eventWrapper) wher

try
{
foreach (var stream in State.Children.Select(GetEventBaseStream))
{
await stream.OnNextAsync(eventWrapper);
}
var streamForChildren = GetEventBaseStreamForChildren(GrainId);
await streamForChildren.OnNextAsync(eventWrapper);
}
catch (Exception ex)
{
Expand Down
64 changes: 51 additions & 13 deletions src/Aevatar.Core/GAgentBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Collections.Concurrent;
using Aevatar.Core.Abstractions;
using Aevatar.Core.Abstractions.Projections;
using Microsoft.Extensions.DependencyInjection;
Expand Down Expand Up @@ -45,7 +44,11 @@ public abstract partial class
private Lazy<IStreamProvider> LazyStreamProvider => new(()
=> this.GetStreamProvider(AevatarCoreConstants.StreamProvider));

private Lazy<IGAgentFactory> LazyGAgentFactory => new(()
=> ServiceProvider.GetRequiredService<IGAgentFactory>());

protected IStreamProvider StreamProvider => LazyStreamProvider.Value;
protected IGAgentFactory GAgentFactory => LazyGAgentFactory.Value;

public ILogger Logger { get; set; } = NullLogger.Instance;

Expand Down Expand Up @@ -74,12 +77,16 @@ public async Task RegisterAsync(IGAgent gAgent)

public async Task SubscribeToAsync(IGAgent gAgent)
{
var parentGrainId = gAgent.GetGrainId();
var parentStream = GetEventBaseStreamForChildren(parentGrainId);
var asyncObserver = new GAgentAsyncObserver(_observers);
await ResumeOrSubscribeAsync(parentStream, asyncObserver);
await SetParentAsync(gAgent.GetGrainId());
}

public Task UnsubscribeFromAsync(IGAgent gAgent)
public async Task UnsubscribeFromAsync(IGAgent gAgent)
{
return ClearParentAsync(gAgent.GetGrainId());
await ClearParentAsync(gAgent.GetGrainId());
}

public async Task UnregisterAsync(IGAgent gAgent)
Expand All @@ -89,7 +96,7 @@ public async Task UnregisterAsync(IGAgent gAgent)
await OnUnregisterAgentAsync(gAgent.GetGrainId());
}

public virtual Task<List<Type>?> GetAllSubscribedEventsAsync(bool includeBaseHandlers = false)
public async virtual Task<List<Type>?> GetAllSubscribedEventsAsync(bool includeBaseHandlers = false)
{
var eventHandlerMethods = GetEventHandlerMethods(GetType());
eventHandlerMethods = eventHandlerMethods.Where(m =>
Expand All @@ -101,7 +108,7 @@ public async Task UnregisterAsync(IGAgent gAgent)
handlingTypes = handlingTypes.Where(t => t != typeof(RequestAllSubscriptionsEvent));
}

return Task.FromResult(handlingTypes.ToList())!;
return handlingTypes.ToList();
}

public Task<List<GrainId>> GetChildrenAsync()
Expand All @@ -127,6 +134,18 @@ public async Task ConfigAsync(ConfigurationBase configuration)
}
}

public async Task<IAsyncObserver<EventWrapperBase>> GetGAgentAsyncObserverAsync()
{
var asyncObserver = new GAgentAsyncObserver(_observers);
return asyncObserver;
}

public async Task ResumeSubscriptionAsync(IAsyncStream<EventWrapperBase> stream)
{
var asyncObserver = new GAgentAsyncObserver(_observers);
await ResumeOrSubscribeAsync(stream, asyncObserver);
}

protected virtual Task PerformConfigAsync(TConfiguration configuration)
{
return Task.CompletedTask;
Expand Down Expand Up @@ -238,21 +257,35 @@ private async Task BaseOnActivateAsync(CancellationToken cancellationToken)
var initTasks = new[]
{
InitializeOrResumeEventBaseStreamAsync(),
ResumeEventBaseStreamForChildrenAsync(),
ActivateProjectionGrainAsync()
};
await Task.WhenAll(initTasks);
}

private async Task InitializeOrResumeEventBaseStreamAsync()
{
var streamOfThisGAgent = GetEventBaseStream(this.GetGrainId());
var streamOfThisGAgent = GetEventBaseStreamForOwn(this.GetGrainId());
var asyncObserver = new GAgentAsyncObserver(_observers);
await ResumeOrSubscribeAsync(streamOfThisGAgent, asyncObserver);
}

private async Task ResumeEventBaseStreamForChildrenAsync()
{
var streamForChildren = GetEventBaseStreamForChildren(this.GetGrainId());
var tasks = new List<Task>();
foreach (var childGrainId in State.Children)
{
var child = await GAgentFactory.GetGAgentAsync(childGrainId);
tasks.Add(child.ResumeSubscriptionAsync(streamForChildren));
}

await Task.WhenAll(tasks);
}

private async Task ActivateProjectionGrainAsync()
{
var projectionGrain = GrainFactory.GetGrain<IProjectionGrain<TState>>(Guid.Empty);
var projectionGrain = GrainFactory.GetGrain<IProjectionGrain>(typeof(TState).FullName);
await projectionGrain.ActivateAsync();
}

Expand Down Expand Up @@ -330,16 +363,21 @@ protected virtual Task HandleRaiseEventAsync()
return Task.CompletedTask;
}

private IAsyncStream<EventWrapperBase> GetEventBaseStream(GrainId grainId)
private IAsyncStream<EventWrapperBase> GetEventBaseStreamForOwn(GrainId grainId)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This naming convention is very difficult to understand. Can't really explain how for own is linked to its implementation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about changing it to GetEventBaseUpwardsStream?

{
var grainIdString = grainId.ToString();
var streamId = StreamId.Create(AevatarOptions!.StreamNamespace, grainIdString);
return StreamProvider.GetStream<EventWrapperBase>(streamId);
return GetEventBaseStream(grainIdString);
}

private IAsyncStream<StateWrapper<TState>> GetStateProjectionStream()
private IAsyncStream<EventWrapperBase> GetEventBaseStreamForChildren(GrainId grainId)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetEventBaseDownwardStream what do you think?

{
var streamId = StreamId.Create(AevatarOptions!.StreamNamespace, typeof(StateWrapper<TState>).FullName!);
return StreamProvider.GetStream<StateWrapper<TState>>(streamId);
var grainIdString = $"{grainId.ToString()}/Children";
return GetEventBaseStream(grainIdString);
}

private IAsyncStream<EventWrapperBase> GetEventBaseStream(string streamKey)
{
var streamId = StreamId.Create(AevatarOptions!.StreamNamespace, streamKey);
return StreamProvider.GetStream<EventWrapperBase>(streamId);
}
}
Loading