Skip to content
This repository was archived by the owner on Mar 31, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all 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
14 changes: 14 additions & 0 deletions AISmart.sln
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AISmart.CQRS", "src\AISmart
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AISmart.Rag.Contracts", "src\AISmart.Rag.Contracts\AISmart.Rag.Contracts.csproj", "{3A58DC0A-BA95-48B9-9468-F7892A71F4FA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AISmart.GAgent.Core.Context", "src\AISmart.GAgent.Core.Context\AISmart.GAgent.Core.Context.csproj", "{AC8AE7DC-B3D0-4C2D-A905-CB1D0F4F08F0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AISmart.GAgent.EventContext", "src\AISmart.GAgent.EventContext\AISmart.GAgent.EventContext.csproj", "{61716D0E-9B1E-47D1-BED6-47D1C034B237}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -269,6 +273,14 @@ Global
{3A58DC0A-BA95-48B9-9468-F7892A71F4FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3A58DC0A-BA95-48B9-9468-F7892A71F4FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3A58DC0A-BA95-48B9-9468-F7892A71F4FA}.Release|Any CPU.Build.0 = Release|Any CPU
{AC8AE7DC-B3D0-4C2D-A905-CB1D0F4F08F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC8AE7DC-B3D0-4C2D-A905-CB1D0F4F08F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC8AE7DC-B3D0-4C2D-A905-CB1D0F4F08F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC8AE7DC-B3D0-4C2D-A905-CB1D0F4F08F0}.Release|Any CPU.Build.0 = Release|Any CPU
{61716D0E-9B1E-47D1-BED6-47D1C034B237}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61716D0E-9B1E-47D1-BED6-47D1C034B237}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61716D0E-9B1E-47D1-BED6-47D1C034B237}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61716D0E-9B1E-47D1-BED6-47D1C034B237}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -316,6 +328,8 @@ Global
{89A0820D-CBB0-4061-A939-F30EF486BA93} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
{23A8822F-83B5-4ABA-B05B-BAE9670ACD68} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
{3A58DC0A-BA95-48B9-9468-F7892A71F4FA} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
{AC8AE7DC-B3D0-4C2D-A905-CB1D0F4F08F0} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
{61716D0E-9B1E-47D1-BED6-47D1C034B237} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F}
Expand Down
3 changes: 1 addition & 2 deletions src/AISmart.Application.Contracts/Agents/EventWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@ public class EventWrapper<T> : EventWrapperBase
[Id(3)] public GrainId? ContextStorageGrainId { get; set; }

// Constructor
public EventWrapper(T @event, Guid eventId, GrainId grainId, GrainId? contextStorageGrainId)
public EventWrapper(T @event, Guid eventId, GrainId grainId, GrainId? contextStorageGrainId = null)
{
Event = @event;
EventId = eventId;
GrainId = grainId;
ContextStorageGrainId = contextStorageGrainId;

}

// Optionally, you can add methods or other functionality as needed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<ProjectReference Include="..\AISmart.Domain.Grains\AISmart.Domain.Grains.csproj" />
<ProjectReference Include="..\AISmart.Domain\AISmart.Domain.csproj" />
<ProjectReference Include="..\AISmart.GAgent.Core\AISmart.GAgent.Core.csproj" />
<ProjectReference Include="..\AISmart.GAgent.EventContext\AISmart.GAgent.EventContext.csproj" />
<ProjectReference Include="..\AISmart.GAgent.Twitter\AISmart.GAgent.Twitter.csproj" />
<ProjectReference Include="..\AISmart.CQRS\AISmart.CQRS.csproj" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class PublishingAgentState : StateBase

[StorageProvider(ProviderName = "PubSubStore")]
[LogConsistencyProvider(ProviderName = "LogStorage")]
public class PublishingGAgent : GAgentBase<PublishingAgentState, PublishingGEvent>, IPublishingGAgent
public class PublishingGAgent : ContextGAgentBase<PublishingAgentState, PublishingGEvent>, IPublishingGAgent
{
public PublishingGAgent(ILogger<PublishingGAgent> logger) : base(logger)
{
Expand Down
20 changes: 20 additions & 0 deletions src/AISmart.GAgent.Core.Context/AISmart.GAgent.Core.Context.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Orleans.Core.Abstractions" />
<PackageReference Include="Microsoft.Orleans.Reminders" />
<PackageReference Include="Microsoft.Orleans.Runtime" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\AISmart.Core\AISmart.Core.csproj" />
<ProjectReference Include="..\AISmart.Application.Contracts\AISmart.Application.Contracts.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace AISmart.GAgent.Core.Context;

public class AISmartGAgentContextConstants
{
public const string ContextStorageGrainSelfTerminateReminderName = "DeleteSelfReminder";
public static TimeSpan DefaultContextStorageGrainSelfDeleteTime = TimeSpan.FromMinutes(10);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Microsoft.Extensions.Logging;

namespace AISmart.GAgent.Core;
namespace AISmart.GAgent.Core.Context;

public sealed class ContextStorageState
{
Expand Down Expand Up @@ -85,16 +85,16 @@ public async Task ReceiveReminder(string reminderName, TickStatus status)
public async Task ResetSelfTerminateTime(TimeSpan timeSpan)
{
_reminder = await this.RegisterOrUpdateReminder(
AISmartGAgentConstants.ContextStorageGrainSelfTerminateReminderName,
AISmartGAgentContextConstants.ContextStorageGrainSelfTerminateReminderName,
timeSpan, timeSpan);
}

public override async Task OnActivateAsync(CancellationToken cancellationToken)
{
_reminder = await this.RegisterOrUpdateReminder(
AISmartGAgentConstants.ContextStorageGrainSelfTerminateReminderName,
AISmartGAgentConstants.DefaultContextStorageGrainSelfDeleteTime,
AISmartGAgentConstants.DefaultContextStorageGrainSelfDeleteTime);
AISmartGAgentContextConstants.ContextStorageGrainSelfTerminateReminderName,
AISmartGAgentContextConstants.DefaultContextStorageGrainSelfDeleteTime,
AISmartGAgentContextConstants.DefaultContextStorageGrainSelfDeleteTime);
await base.OnActivateAsync(cancellationToken);
}
}
37 changes: 37 additions & 0 deletions src/AISmart.GAgent.Core.Context/ContextStorageHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using AISmart.Agents;

namespace AISmart.GAgent.Core.Context;

public class ContextStorageHelper
{
private readonly IGrainFactory? _grainFactory;

public ContextStorageHelper(IGrainFactory grainFactory)
{
_grainFactory = grainFactory;
}

public async Task<GrainId?> SetContextAsync(EventWrapperBase item, EventBase eventType)
{
if (_grainFactory == null)
{
return null;
}

var contextStorageGrainIdValue = item.GetType()
.GetProperty(nameof(EventWrapper<EventBase>.ContextStorageGrainId))?
.GetValue(item);
GrainId? contextStorageGrainId = null;
if (contextStorageGrainIdValue == null)
{
return contextStorageGrainId;
}

contextStorageGrainId = (GrainId)contextStorageGrainIdValue;
var contextStorageGrain =
_grainFactory.GetGrain<IContextStorageGrain>(contextStorageGrainId.Value.GetGuidKey());
var context = await contextStorageGrain.GetContext();
eventType.SetContext(context);
return contextStorageGrainId;
}
}
56 changes: 56 additions & 0 deletions src/AISmart.GAgent.Core.Context/EventContextExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
namespace AISmart.GAgent.Core.Context;

public static class EventContextExtensions
{
public static async Task SetContextAsync(this IEventContext context, string key, object? value)
{
if (context.ContextStorageGrainId != null)
{
var contextStorageGrain =
context.GrainFactory.GetGrain<IContextStorageGrain>(context.ContextStorageGrainId.Value.GetGuidKey());
await contextStorageGrain.AddContext(key, value);
}
}

public static async Task SetContextAsync(this IEventContext context, Dictionary<string, object?> contextData)
{
if (context.ContextStorageGrainId != null)
{
var contextStorageGrain =
context.GrainFactory.GetGrain<IContextStorageGrain>(context.ContextStorageGrainId.Value.GetGuidKey());
await contextStorageGrain.AddContext(contextData);
}
}

public static async Task ResetContextStorageGrainTerminateTimeAsync(this IEventContext context, TimeSpan timeSpan)
{
if (context.ContextStorageGrainId != null)
{
var contextStorageGrain =
context.GrainFactory.GetGrain<IContextStorageGrain>(context.ContextStorageGrainId.Value.GetGuidKey());
await contextStorageGrain.ResetSelfTerminateTime(timeSpan);
}
}

public static async Task<Dictionary<string, object?>> GetContextAsync(this IEventContext context)
{
if (context.ContextStorageGrainId != null)
{
var contextStorageGrain =
context.GrainFactory.GetGrain<IContextStorageGrain>(context.ContextStorageGrainId.Value.GetGuidKey());
return await contextStorageGrain.GetContext();
}

return new Dictionary<string, object?>();
}

public static void SetContextStorageGrainId(this IEventContext context, GrainId? grainId)
{
context.ContextStorageGrainId = grainId;
}

public static void ClearContext(this IEventContext context)
{
context.ContextStorageGrainId = null;
}
}
9 changes: 9 additions & 0 deletions src/AISmart.GAgent.Core.Context/IEventContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace AISmart.GAgent.Core.Context;

public interface IEventContext
{
GrainId? ContextStorageGrainId { get; set; }
IGrainFactory GrainFactory { get; }
void SetContextStorageGrainId(GrainId? grainId);
void ClearContext();
}
1 change: 1 addition & 0 deletions src/AISmart.GAgent.Core/AISmart.GAgent.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<ItemGroup>
<ProjectReference Include="..\AISmart.Application.Contracts\AISmart.Application.Contracts.csproj" />
<ProjectReference Include="..\AISmart.Core\AISmart.Core.csproj" />
<ProjectReference Include="..\AISmart.GAgent.Core.Context\AISmart.GAgent.Core.Context.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 0 additions & 2 deletions src/AISmart.GAgent.Core/AISmartGAgentConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,4 @@ public static class AISmartGAgentConstants
public const string SubscribersStateName = "Subscribers";
public const string SubscriptionsStateName = "Subscriptions";
public const string PublishersStateName = "Publishers";
public const string ContextStorageGrainSelfTerminateReminderName = "DeleteSelfReminder";
public static TimeSpan DefaultContextStorageGrainSelfDeleteTime = TimeSpan.FromMinutes(10);
}
60 changes: 0 additions & 60 deletions src/AISmart.GAgent.Core/GAgentBase.Context.cs

This file was deleted.

23 changes: 11 additions & 12 deletions src/AISmart.GAgent.Core/GAgentBase.Observers.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Reflection;
using AISmart.Agents;
using AISmart.GAgent.Core.Context;
using Microsoft.Extensions.Logging;

namespace AISmart.GAgent.Core;
Expand All @@ -14,27 +15,26 @@ private Task UpdateObserverList()
{
var observer = new EventWrapperBaseAsyncObserver(async item =>
{
var grainId = (GrainId)item.GetType().GetProperty(nameof(EventWrapper<object>.GrainId))?.GetValue(item)!;
var grainId =
(GrainId)item.GetType().GetProperty(nameof(EventWrapper<object>.GrainId))?.GetValue(item)!;
if (grainId == this.GetGrainId())
{
// Skip the event if it is sent by itself.
return;
}

var eventId = (Guid)item.GetType().GetProperty(nameof(EventWrapper<EventBase>.EventId))?.GetValue(item)!;
var eventId = (Guid)item.GetType().GetProperty(nameof(EventWrapper<EventBase>.EventId))
?.GetValue(item)!;
var eventType = item.GetType().GetProperty(nameof(EventWrapper<EventBase>.Event))?.GetValue(item);
var parameter = eventHandlerMethod.GetParameters()[0];

var contextStorageGrainIdValue = item.GetType()
.GetProperty(nameof(EventWrapper<EventBase>.ContextStorageGrainId))?
.GetValue(item);
GrainId? contextStorageGrainId = null;
if (contextStorageGrainIdValue != null)

if (this is IEventContext)
{
contextStorageGrainId = (GrainId)contextStorageGrainIdValue;
var contextStorageGrain = GrainFactory.GetGrain<IContextStorageGrain>(contextStorageGrainId.Value.GetGuidKey());
var context = await contextStorageGrain.GetContext();
(eventType! as EventBase)!.SetContext(context);
var contextStorageHelper = new ContextStorageHelper(GrainFactory);
contextStorageGrainId = await contextStorageHelper.SetContextAsync(item, (EventBase)eventType!);
((IEventContext)this).SetContextStorageGrainId(contextStorageGrainId);
}

if (parameter.ParameterType == eventType!.GetType())
Expand All @@ -61,7 +61,7 @@ await HandleMethodInvocationAsync(eventHandlerMethod, parameter, eventType, even
}
}

ClearContext();
(this as IEventContext)?.ClearContext();
});

Observers.Add(observer, new Dictionary<StreamId, Guid>());
Expand Down Expand Up @@ -104,7 +104,6 @@ private async Task HandleMethodInvocationAsync(MethodInfo method, ParameterInfo
{
try
{
SetContextStorageGrainId(contextStorageGrainId);
var result = method.Invoke(this, [eventType]);
await (Task)result!;
}
Expand Down
Loading