have akka.net and signalr communicating

This commit is contained in:
2024-03-19 17:17:49 -06:00
parent 09e97fb2fc
commit 9ffd60ac84
17 changed files with 322 additions and 29 deletions

View File

@@ -0,0 +1,50 @@
using System.Diagnostics;
using System.Net.Http.Headers;
using Akka.Actor;
using Akka.DependencyInjection;
using Management.Services.Canvas;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
namespace Management.Actors;
// RecieveActor configures messages in constructor
// UntypedActor configures messages in an onrecieved function
public class CanvasApiActor : ReceiveActor
{
private readonly IServiceScope _scope;
private readonly ILogger<CanvasApiActor> _logger;
private readonly IHubContext<SignalRHub> _hub;
public CanvasApiActor(IServiceProvider serviceProvider) // props go here
{
_scope = serviceProvider.CreateScope();
_logger = _scope.ServiceProvider.GetRequiredService<ILogger<CanvasApiActor>>();
_hub = _scope.ServiceProvider.GetRequiredService<IHubContext<SignalRHub>>();
_logger.LogInformation("creating canvas actor");
var canvasService = _scope.ServiceProvider.GetRequiredService<CanvasService>();
ReceiveAsync<GetModulesMessage>(async m =>
{
using var activity = m.Activity("canvas actor getting modules from canvas api");
var modules = await canvasService.Modules.GetModules(m.CanvasCourseId);
Sender.Tell(new CanvasModulesMessage(m.RequestId, m.CanvasCourseId, modules, activity?.TraceId, activity?.SpanId));
await _hub.Clients.Client(m.ClientConnectionId).SendAsync("SentFromActor");
});
}
protected override void PostStop()
{
_scope.Dispose();
base.PostStop();
}
// used to wrap the arguments in a comprehension for future instanciation of the actor
// does this work with DI?
// public static Props Props(CanvasService canvasService) =>
// Akka.Actor.Props.Create(() => new CanvasApiActor(canvasService));
}

View File

@@ -0,0 +1,15 @@
using Akka.Actor;
using Akka.DependencyInjection;
namespace Management.Actors;
public class CanvasSupervisor : ReceiveActor
{
// private IActorRef canvasApiActor;
// public CanvasSupervisor()
// {
// // DependencyResolver
// }
}

View File

@@ -0,0 +1,12 @@
using System.Diagnostics;
using CanvasModel.Modules;
namespace Management.Actors;
public sealed record CanvasModulesMessage(
long RequestId,
ulong CanvasCourseId,
IEnumerable<CanvasModule> CanvasModules,
ActivityTraceId? ParentTrace,
ActivitySpanId? ParentSpan
) : ITraceableMessage;

View File

@@ -0,0 +1,11 @@
using System.Diagnostics;
namespace Management.Actors;
public sealed record GetModulesMessage(
long RequestId,
ulong CanvasCourseId,
string ClientConnectionId,
ActivityTraceId? ParentTrace,
ActivitySpanId? ParentSpan
) : ITraceableMessage;

View File

@@ -0,0 +1,8 @@
using System.Diagnostics;
public interface ITraceableMessage
{
public ActivitySpanId? ParentSpan {get;}
public ActivityTraceId? ParentTrace {get;}
}

View File

@@ -1,7 +1,23 @@
using System.Diagnostics;
using System.Security.Policy;
public static class DiagnosticsConfig
{
public const string SourceName = "canvas-management-source";
public static ActivitySource Source = new ActivitySource(SourceName);
public readonly static ActivitySource Source = new(SourceName);
public static Activity? Activity(this ITraceableMessage message, string activityName)
{
if (message.ParentTrace != null && message.ParentSpan != null)
{
ActivityContext parentContext = new ActivityContext(
(ActivityTraceId)message.ParentTrace,
(ActivitySpanId)message.ParentSpan,
ActivityTraceFlags.Recorded
);
return Source?.StartActivity(activityName, ActivityKind.Internal, parentContext);
}
return Source?.StartActivity(activityName);
}
}

View File

@@ -44,7 +44,6 @@ public class CoursePlanner
get => _localCourse;
set
{
using var activity = DiagnosticsConfig.Source?.StartActivity("Loading Course");
if (value == null)
{
_localCourse = null;

View File

@@ -7,7 +7,11 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Akka" Version="1.5.18" />
<PackageReference Include="Akka.DependencyInjection" Version="1.5.18" />
<PackageReference Include="Markdig" Version="0.31.0" />
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="8.0.3" />
<PackageReference Include="microsoft.extensions.configuration.abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="RestSharp" Version="108.0.3" />

15
Management/SignalRHub.cs Normal file
View File

@@ -0,0 +1,15 @@
using Microsoft.AspNetCore.SignalR;
public class SignalRHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
public override Task OnConnectedAsync()
{
var connectionId = Context.ConnectionId;
// Store the connection ID for later use, e.g., in a database or in-memory store
return base.OnConnectedAsync();
}
}