mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
removed akka.net
This commit is contained in:
@@ -1,62 +0,0 @@
|
|||||||
|
|
||||||
using Akka.Actor;
|
|
||||||
using Akka.DependencyInjection;
|
|
||||||
namespace Management.Actors;
|
|
||||||
|
|
||||||
|
|
||||||
public class AkkaService : IHostedService, IActorBridge
|
|
||||||
{
|
|
||||||
private ActorSystem? _actorSystem;
|
|
||||||
private readonly IConfiguration _configuration;
|
|
||||||
private readonly IServiceProvider _serviceProvider;
|
|
||||||
private IActorRef? _canvasApiActor;
|
|
||||||
private readonly IHostApplicationLifetime _applicationLifetime;
|
|
||||||
|
|
||||||
public AkkaService(IServiceProvider serviceProvider, IHostApplicationLifetime appLifetime, IConfiguration configuration)
|
|
||||||
{
|
|
||||||
_serviceProvider = serviceProvider;
|
|
||||||
_applicationLifetime = appLifetime;
|
|
||||||
_configuration = configuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task StartAsync(CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var bootstrap = BootstrapSetup.Create();
|
|
||||||
var dependencyInjectionSetup = DependencyResolverSetup.Create(_serviceProvider);
|
|
||||||
|
|
||||||
var mergedSystemSetup = bootstrap.And(dependencyInjectionSetup);
|
|
||||||
|
|
||||||
_actorSystem = ActorSystem.Create("canvas-managment-actors", mergedSystemSetup);
|
|
||||||
|
|
||||||
// start top level supervisor actor
|
|
||||||
|
|
||||||
// working here https://getakka.net/articles/actors/dependency-injection.html#integrating-with-microsoftextensionsdependencyinjection
|
|
||||||
var apiActorProps = DependencyResolver.For(_actorSystem).Props<CanvasApiActor>();
|
|
||||||
_canvasApiActor = _actorSystem.ActorOf(apiActorProps, "canvas-api");
|
|
||||||
|
|
||||||
// crash if the actor system crashes, awaiting never returns...
|
|
||||||
#pragma warning disable CA2016 // Forward the 'CancellationToken' parameter to methods
|
|
||||||
_actorSystem.WhenTerminated.ContinueWith(tr =>
|
|
||||||
{
|
|
||||||
_applicationLifetime.StopApplication();
|
|
||||||
});
|
|
||||||
#pragma warning restore CA2016 // Forward the 'CancellationToken' parameter to methods
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
|
||||||
|
|
||||||
|
|
||||||
// add more methods to interact with actor processes, make them part of an interface
|
|
||||||
// these are the most generic forwarding of messages
|
|
||||||
public void Tell(object message)
|
|
||||||
{
|
|
||||||
_canvasApiActor.Tell(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<T> Ask<T>(object message)
|
|
||||||
{
|
|
||||||
return _canvasApiActor.Ask<T>(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace Management.Actors;
|
|
||||||
|
|
||||||
public interface IActorBridge
|
|
||||||
{
|
|
||||||
void Tell(object message);
|
|
||||||
Task<T> Ask<T>(object message);
|
|
||||||
}
|
|
||||||
@@ -5,8 +5,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Akka" Version="1.5.18" />
|
|
||||||
<PackageReference Include="Akka.DependencyInjection" Version="1.5.18" />
|
|
||||||
<PackageReference Include="BlazorMonaco" Version="3.0.0" />
|
<PackageReference Include="BlazorMonaco" Version="3.0.0" />
|
||||||
<PackageReference Include="dotenv.net" Version="3.1.2" />
|
<PackageReference Include="dotenv.net" Version="3.1.2" />
|
||||||
<PackageReference Include="Markdig" Version="0.31.0" />
|
<PackageReference Include="Markdig" Version="0.31.0" />
|
||||||
|
|||||||
@@ -1,64 +1,11 @@
|
|||||||
@page "/test"
|
@page "/test"
|
||||||
@rendermode InteractiveServer
|
@rendermode InteractiveServer
|
||||||
|
|
||||||
@using Microsoft.AspNetCore.SignalR.Client
|
|
||||||
|
|
||||||
@inject CanvasService canvas
|
@inject CanvasService canvas
|
||||||
@inject CoursePlanner planner
|
@inject CoursePlanner planner
|
||||||
@inject FileStorageManager fileStorageManager
|
@inject FileStorageManager fileStorageManager
|
||||||
@inject IActorBridge bridge
|
|
||||||
@inject NavigationManager Navigation
|
@inject NavigationManager Navigation
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private HubConnection? hubConnection;
|
|
||||||
public string? CourseName = "1400";
|
|
||||||
@* private bool loading = true; *@
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
if (planner.LocalCourse == null)
|
|
||||||
{
|
|
||||||
System.Diagnostics.Activity.Current = null;
|
|
||||||
using var activity = DiagnosticsConfig.Source?.StartActivity("Loading Course");
|
|
||||||
activity?.AddTag("CourseName", CourseName);
|
|
||||||
var courses = await fileStorageManager.LoadSavedCourses();
|
|
||||||
planner.LocalCourse = courses.First(c => c.Settings.Name == CourseName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@* Console.WriteLine(Navigation.BaseUri + "SignalRHub"); *@
|
|
||||||
hubConnection = new HubConnectionBuilder()
|
|
||||||
.WithUrl(Navigation.BaseUri + "SignalRHub")
|
|
||||||
.WithAutomaticReconnect()
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
|
|
||||||
hubConnection.On("SentFromActor", () =>
|
|
||||||
{
|
|
||||||
Console.WriteLine("recieved from actor");
|
|
||||||
});
|
|
||||||
|
|
||||||
await hubConnection.StartAsync();
|
|
||||||
|
|
||||||
base.OnInitialized();
|
|
||||||
@* loading = false; *@
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SendAkkaMessage()
|
|
||||||
{
|
|
||||||
System.Diagnostics.Activity.Current = null;
|
|
||||||
using var activity = DiagnosticsConfig.Source?.StartActivity("sending akka message from blazor");
|
|
||||||
|
|
||||||
if (planner.LocalCourse != null && planner.LocalCourse.Settings.CanvasId != null && hubConnection?.ConnectionId != null)
|
|
||||||
{
|
|
||||||
ulong id = (ulong)planner.LocalCourse.Settings.CanvasId;
|
|
||||||
|
|
||||||
var message = new GetModulesMessage(0, id, (string)hubConnection.ConnectionId, activity?.TraceId, ParentSpan:
|
|
||||||
activity?.SpanId);
|
|
||||||
var response = await bridge.Ask<CanvasModulesMessage>(message);
|
|
||||||
Console.WriteLine(response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<button @onclick=SendAkkaMessage>test akka</button>
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ global using Management.Services.Canvas;
|
|||||||
global using Management.Web.Shared;
|
global using Management.Web.Shared;
|
||||||
global using Management.Web.Shared.Components;
|
global using Management.Web.Shared.Components;
|
||||||
using dotenv.net;
|
using dotenv.net;
|
||||||
using Management.Actors;
|
|
||||||
using Microsoft.AspNetCore.Hosting.Server;
|
using Microsoft.AspNetCore.Hosting.Server;
|
||||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||||
using Microsoft.AspNetCore.ResponseCompression;
|
using Microsoft.AspNetCore.ResponseCompression;
|
||||||
@@ -93,13 +92,6 @@ builder.Services.AddScoped<DragContainer>();
|
|||||||
|
|
||||||
builder.Services.AddSingleton<FileConfiguration>();
|
builder.Services.AddSingleton<FileConfiguration>();
|
||||||
|
|
||||||
|
|
||||||
// exposing actor service to controllers
|
|
||||||
builder.Services.AddSingleton<IActorBridge, AkkaService>();
|
|
||||||
|
|
||||||
// starting actor service while enabling it to use dependency injection
|
|
||||||
builder.Services.AddHostedService<AkkaService>(sp => (AkkaService)sp.GetRequiredService<IActorBridge>());
|
|
||||||
|
|
||||||
builder.Services.AddResponseCompression(opts =>
|
builder.Services.AddResponseCompression(opts =>
|
||||||
{
|
{
|
||||||
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] { "application/octet-stream" });
|
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] { "application/octet-stream" });
|
||||||
|
|||||||
@@ -8,5 +8,4 @@
|
|||||||
@using Microsoft.JSInterop
|
@using Microsoft.JSInterop
|
||||||
@using Management.Web
|
@using Management.Web
|
||||||
@using Management.Web.Shared
|
@using Management.Web.Shared
|
||||||
@using Management.Actors
|
|
||||||
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
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));
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
using Akka.Actor;
|
|
||||||
using Akka.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Management.Actors;
|
|
||||||
|
|
||||||
public class CanvasSupervisor : ReceiveActor
|
|
||||||
{
|
|
||||||
// private IActorRef canvasApiActor;
|
|
||||||
|
|
||||||
// public CanvasSupervisor()
|
|
||||||
// {
|
|
||||||
// // DependencyResolver
|
|
||||||
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
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;
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace Management.Actors;
|
|
||||||
|
|
||||||
public sealed record GetModulesMessage(
|
|
||||||
long RequestId,
|
|
||||||
ulong CanvasCourseId,
|
|
||||||
string ClientConnectionId,
|
|
||||||
ActivityTraceId? ParentTrace,
|
|
||||||
ActivitySpanId? ParentSpan
|
|
||||||
) : ITraceableMessage;
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
public interface ITraceableMessage
|
|
||||||
{
|
|
||||||
public ActivitySpanId? ParentSpan { get; }
|
|
||||||
public ActivityTraceId? ParentTrace { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -5,19 +5,4 @@ public static class DiagnosticsConfig
|
|||||||
{
|
{
|
||||||
public const string SourceName = "canvas-management-source";
|
public const string SourceName = "canvas-management-source";
|
||||||
public readonly static ActivitySource Source = new(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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,6 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<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="Markdig" Version="0.31.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="8.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="8.0.3" />
|
||||||
|
|||||||
25
README.md
25
README.md
@@ -21,3 +21,28 @@ matching questions
|
|||||||
|
|
||||||
- different delimiter (-n in answer messes things up)
|
- different delimiter (-n in answer messes things up)
|
||||||
- add distractors
|
- add distractors
|
||||||
|
|
||||||
|
|
||||||
|
on calendar month, displays days that are on the same week as a month change (if month ends on monday, still show tues-sat)
|
||||||
|
|
||||||
|
file uploads
|
||||||
|
- image compression?
|
||||||
|
- scrape html, when image embedded, upload to canvas and add img tag to canvas asset in html before sending image
|
||||||
|
|
||||||
|
add grade percentage support in page
|
||||||
|
|
||||||
|
wait until week two before colapsing previous month?
|
||||||
|
|
||||||
|
better ux around course settings (assignment groups, term for start/end)
|
||||||
|
|
||||||
|
display queue of canvas requests
|
||||||
|
|
||||||
|
allow multiple courses to be edited concurrently in different browser tabs
|
||||||
|
|
||||||
|
have lock date mimic an offset after drag and drop changes due date
|
||||||
|
|
||||||
|
make the ux easier to change course pages
|
||||||
|
|
||||||
|
schedule planning view? just outline concepts? (maybe some non-canvas scheduled thing that only shows up in planner? like a note, could be de-emphasized in webpage)
|
||||||
|
|
||||||
|
holiday schedule
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ services:
|
|||||||
- ~/projects/faculty/1430/2024-fall-alex/modules:/app/storage/fall_ux
|
- ~/projects/faculty/1430/2024-fall-alex/modules:/app/storage/fall_ux
|
||||||
- ~/projects/faculty/4850_AdvancedFE/2024-fall-alex/modules:/app/storage/fall_advanced_frontend
|
- ~/projects/faculty/4850_AdvancedFE/2024-fall-alex/modules:/app/storage/fall_advanced_frontend
|
||||||
- ~/projects/faculty/1810/2024-fall-alex/modules:/app/storage/fall_intro_to_web
|
- ~/projects/faculty/1810/2024-fall-alex/modules:/app/storage/fall_intro_to_web
|
||||||
- ~/projects/faculty/1420/2024-fall/modules:/app/storage/fall_1420
|
- ~/projects/faculty/1420/2024-fall/Modules:/app/storage/fall_1420
|
||||||
- ~/projects/faculty/1425/2024-fall/modules:/app/storage/fall_1425
|
- ~/projects/faculty/1425/2024-fall/Modules:/app/storage/fall_1425
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user