mirror of https://github.com/dapr/dotnet-sdk.git
Remove static instance of ActorRuntime
Contributes to: #416 This change removes a mutable static instance - this is low-hanging fruit design improvement and helps us make these features more flexible in the future.
This commit is contained in:
parent
a061b726b6
commit
cd781248c7
|
|
@ -10,31 +10,35 @@ namespace Dapr.Actors.AspNetCore
|
|||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
internal static class EndpointRouteBuilderExtensions
|
||||
{
|
||||
public static IEndpointConventionBuilder AddDaprConfigRoute(this IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
var runtime = endpoints.ServiceProvider.GetRequiredService<ActorRuntime>();
|
||||
return endpoints.MapGet("dapr/config", async context =>
|
||||
{
|
||||
context.Response.ContentType = "application/json";
|
||||
await ActorRuntime.Instance.SerializeSettingsAndRegisteredTypes(context.Response.BodyWriter);
|
||||
await runtime.SerializeSettingsAndRegisteredTypes(context.Response.BodyWriter);
|
||||
});
|
||||
}
|
||||
|
||||
public static IEndpointConventionBuilder AddActorDeactivationRoute(this IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
var runtime = endpoints.ServiceProvider.GetRequiredService<ActorRuntime>();
|
||||
return endpoints.MapDelete("actors/{actorTypeName}/{actorId}", async context =>
|
||||
{
|
||||
var routeValues = context.Request.RouteValues;
|
||||
var actorTypeName = (string)routeValues["actorTypeName"];
|
||||
var actorId = (string)routeValues["actorId"];
|
||||
await ActorRuntime.DeactivateAsync(actorTypeName, actorId);
|
||||
await runtime.DeactivateAsync(actorTypeName, actorId);
|
||||
});
|
||||
}
|
||||
|
||||
public static IEndpointConventionBuilder AddActorMethodRoute(this IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
var runtime = endpoints.ServiceProvider.GetRequiredService<ActorRuntime>();
|
||||
return endpoints.MapPut("actors/{actorTypeName}/{actorId}/method/{methodName}", async context =>
|
||||
{
|
||||
var routeValues = context.Request.RouteValues;
|
||||
|
|
@ -46,7 +50,7 @@ namespace Dapr.Actors.AspNetCore
|
|||
if (context.Request.Headers.ContainsKey(Constants.RequestHeaderName))
|
||||
{
|
||||
var daprActorheader = context.Request.Headers[Constants.RequestHeaderName];
|
||||
var (header, body) = await ActorRuntime.DispatchWithRemotingAsync(actorTypeName, actorId, methodName, daprActorheader, context.Request.Body);
|
||||
var (header, body) = await runtime.DispatchWithRemotingAsync(actorTypeName, actorId, methodName, daprActorheader, context.Request.Body);
|
||||
|
||||
// Item 1 is header , Item 2 is body
|
||||
if (header != string.Empty)
|
||||
|
|
@ -62,7 +66,7 @@ namespace Dapr.Actors.AspNetCore
|
|||
// write exception info in response.
|
||||
try
|
||||
{
|
||||
await ActorRuntime.DispatchWithoutRemotingAsync(actorTypeName, actorId, methodName, context.Request.Body, context.Response.Body);
|
||||
await runtime.DispatchWithoutRemotingAsync(actorTypeName, actorId, methodName, context.Request.Body, context.Response.Body);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
@ -78,6 +82,7 @@ namespace Dapr.Actors.AspNetCore
|
|||
|
||||
public static IEndpointConventionBuilder AddReminderRoute(this IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
var runtime = endpoints.ServiceProvider.GetRequiredService<ActorRuntime>();
|
||||
return endpoints.MapPut("actors/{actorTypeName}/{actorId}/method/remind/{reminderName}", async context =>
|
||||
{
|
||||
var routeValues = context.Request.RouteValues;
|
||||
|
|
@ -86,12 +91,13 @@ namespace Dapr.Actors.AspNetCore
|
|||
var reminderName = (string)routeValues["reminderName"];
|
||||
|
||||
// read dueTime, period and data from Request Body.
|
||||
await ActorRuntime.FireReminderAsync(actorTypeName, actorId, reminderName, context.Request.Body);
|
||||
await runtime.FireReminderAsync(actorTypeName, actorId, reminderName, context.Request.Body);
|
||||
});
|
||||
}
|
||||
|
||||
public static IEndpointConventionBuilder AddTimerRoute(this IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
var runtime = endpoints.ServiceProvider.GetRequiredService<ActorRuntime>();
|
||||
return endpoints.MapPut("actors/{actorTypeName}/{actorId}/method/timer/{timerName}", async context =>
|
||||
{
|
||||
var routeValues = context.Request.RouteValues;
|
||||
|
|
@ -100,7 +106,7 @@ namespace Dapr.Actors.AspNetCore
|
|||
var timerName = (string)routeValues["timerName"];
|
||||
|
||||
// read dueTime, period and data from Request Body.
|
||||
await ActorRuntime.FireTimerAsync(actorTypeName, actorId, timerName);
|
||||
await runtime.FireTimerAsync(actorTypeName, actorId, timerName);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ namespace Dapr.Actors.AspNetCore
|
|||
using Dapr.Actors.Runtime;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
/// <summary>
|
||||
/// Class containing DaprActor related extension methods for Microsoft.AspNetCore.Hosting.IWebHostBuilder.
|
||||
|
|
@ -36,7 +37,11 @@ namespace Dapr.Actors.AspNetCore
|
|||
return hostBuilder;
|
||||
}
|
||||
|
||||
configureActorRuntime.Invoke(ActorRuntime.Instance);
|
||||
var runtime = new ActorRuntime();
|
||||
if (configureActorRuntime != null)
|
||||
{
|
||||
configureActorRuntime.Invoke(runtime);
|
||||
}
|
||||
|
||||
// Set flag to prevent double service configuration
|
||||
hostBuilder.UseSetting(SettingName, true.ToString());
|
||||
|
|
@ -47,6 +52,8 @@ namespace Dapr.Actors.AspNetCore
|
|||
services.AddRouting();
|
||||
services.AddHealthChecks();
|
||||
services.AddSingleton<IStartupFilter>(new DaprActorSetupFilter());
|
||||
|
||||
services.AddSingleton<ActorRuntime>(runtime);
|
||||
});
|
||||
|
||||
return hostBuilder;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
namespace Dapr.Actors.Runtime
|
||||
{
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
|
|
@ -15,13 +16,8 @@ namespace Dapr.Actors.Runtime
|
|||
/// <summary>
|
||||
/// Contains methods to register actor types. Registering the types allows the runtime to create instances of the actor.
|
||||
/// </summary>
|
||||
public class ActorRuntime
|
||||
public sealed class ActorRuntime
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets ActorRuntime.
|
||||
/// </summary>
|
||||
public static readonly ActorRuntime Instance = new ActorRuntime();
|
||||
|
||||
private const string TraceType = "ActorRuntime";
|
||||
|
||||
// Map of ActorType --> ActorManager.
|
||||
|
|
@ -29,10 +25,6 @@ namespace Dapr.Actors.Runtime
|
|||
|
||||
private ActorSettings actorSettings;
|
||||
|
||||
/// <remarks>
|
||||
/// WARNING: This type is expected to be accessed via the <see cref="Instance" /> singleton instance.
|
||||
/// This constructor is exposed only for unit testing purposes.
|
||||
/// </remarks>
|
||||
internal ActorRuntime()
|
||||
{
|
||||
this.actorSettings = new ActorSettings();
|
||||
|
|
@ -78,7 +70,7 @@ namespace Dapr.Actors.Runtime
|
|||
actorSettingsDelegate.Invoke(this.actorSettings);
|
||||
}
|
||||
|
||||
internal Task SerializeSettingsAndRegisteredTypes(System.Buffers.IBufferWriter<byte> output)
|
||||
internal Task SerializeSettingsAndRegisteredTypes(IBufferWriter<byte> output)
|
||||
{
|
||||
using Utf8JsonWriter writer = new Utf8JsonWriter(output);
|
||||
writer.WriteStartObject();
|
||||
|
|
@ -124,9 +116,9 @@ namespace Dapr.Actors.Runtime
|
|||
/// <param name="actorTypeName">Actor type name to deactivate the actor for.</param>
|
||||
/// <param name="actorId">Actor id for the actor to be deactivated.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
|
||||
internal static async Task DeactivateAsync(string actorTypeName, string actorId)
|
||||
internal async Task DeactivateAsync(string actorTypeName, string actorId)
|
||||
{
|
||||
await Instance.GetActorManager(actorTypeName).DeactivateActor(new ActorId(actorId));
|
||||
await GetActorManager(actorTypeName).DeactivateActor(new ActorId(actorId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -134,14 +126,14 @@ namespace Dapr.Actors.Runtime
|
|||
/// </summary>
|
||||
/// <param name="actorTypeName">Actor type name to invokde the method for.</param>
|
||||
/// <param name="actorId">Actor id for the actor for which method will be invoked.</param>
|
||||
/// <param name="actorMethodName">MEthos name on actor type which will be invoked.</param>
|
||||
/// <param name="actorMethodName">Method name on actor type which will be invoked.</param>
|
||||
/// <param name="daprActorheader">Actor Header.</param>
|
||||
/// <param name="data">Payload for the actor method.</param>
|
||||
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
|
||||
internal static Task<Tuple<string, byte[]>> DispatchWithRemotingAsync(string actorTypeName, string actorId, string actorMethodName, string daprActorheader, Stream data, CancellationToken cancellationToken = default)
|
||||
internal Task<Tuple<string, byte[]>> DispatchWithRemotingAsync(string actorTypeName, string actorId, string actorMethodName, string daprActorheader, Stream data, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Instance.GetActorManager(actorTypeName).DispatchWithRemotingAsync(new ActorId(actorId), actorMethodName, daprActorheader, data, cancellationToken);
|
||||
return GetActorManager(actorTypeName).DispatchWithRemotingAsync(new ActorId(actorId), actorMethodName, daprActorheader, data, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -149,14 +141,14 @@ namespace Dapr.Actors.Runtime
|
|||
/// </summary>
|
||||
/// <param name="actorTypeName">Actor type name to invokde the method for.</param>
|
||||
/// <param name="actorId">Actor id for the actor for which method will be invoked.</param>
|
||||
/// <param name="actorMethodName">MEthos name on actor type which will be invoked.</param>
|
||||
/// <param name="actorMethodName">Method name on actor type which will be invoked.</param>
|
||||
/// <param name="requestBodyStream">Payload for the actor method.</param>
|
||||
/// <param name="responseBodyStream">Response for the actor method.</param>
|
||||
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
|
||||
internal static Task DispatchWithoutRemotingAsync(string actorTypeName, string actorId, string actorMethodName, Stream requestBodyStream, Stream responseBodyStream, CancellationToken cancellationToken = default)
|
||||
internal Task DispatchWithoutRemotingAsync(string actorTypeName, string actorId, string actorMethodName, Stream requestBodyStream, Stream responseBodyStream, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Instance.GetActorManager(actorTypeName).DispatchWithoutRemotingAsync(new ActorId(actorId), actorMethodName, requestBodyStream, responseBodyStream, cancellationToken);
|
||||
return GetActorManager(actorTypeName).DispatchWithoutRemotingAsync(new ActorId(actorId), actorMethodName, requestBodyStream, responseBodyStream, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -168,9 +160,9 @@ namespace Dapr.Actors.Runtime
|
|||
/// <param name="requestBodyStream">Payload for the actor method.</param>
|
||||
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
|
||||
internal static Task FireReminderAsync(string actorTypeName, string actorId, string reminderName, Stream requestBodyStream, CancellationToken cancellationToken = default)
|
||||
internal Task FireReminderAsync(string actorTypeName, string actorId, string reminderName, Stream requestBodyStream, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Instance.GetActorManager(actorTypeName).FireReminderAsync(new ActorId(actorId), reminderName, requestBodyStream, cancellationToken);
|
||||
return GetActorManager(actorTypeName).FireReminderAsync(new ActorId(actorId), reminderName, requestBodyStream, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -181,9 +173,9 @@ namespace Dapr.Actors.Runtime
|
|||
/// <param name="timerName">The name of timer provided during registration.</param>
|
||||
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
|
||||
internal static Task FireTimerAsync(string actorTypeName, string actorId, string timerName, CancellationToken cancellationToken = default)
|
||||
internal Task FireTimerAsync(string actorTypeName, string actorId, string timerName, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Instance.GetActorManager(actorTypeName).FireTimerAsync(new ActorId(actorId), timerName, cancellationToken);
|
||||
return GetActorManager(actorTypeName).FireTimerAsync(new ActorId(actorId), timerName, cancellationToken);
|
||||
}
|
||||
|
||||
private ActorManager GetActorManager(string actorTypeName)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ namespace Dapr.Actors.Test
|
|||
{
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
|
@ -54,18 +53,19 @@ namespace Dapr.Actors.Test
|
|||
|
||||
// This tests the change that removed the Activate message from Dapr runtime -> app.
|
||||
[Fact]
|
||||
public void NoActivateMessageFromRuntime()
|
||||
public async Task NoActivateMessageFromRuntime()
|
||||
{
|
||||
var actorType = typeof(MyActor);
|
||||
|
||||
ActorRuntime.Instance.RegisterActor<MyActor>();
|
||||
var runtime = new ActorRuntime();
|
||||
runtime.RegisterActor<MyActor>();
|
||||
|
||||
var output = new MemoryStream();
|
||||
ActorRuntime.DispatchWithoutRemotingAsync("MyActor", "abc", "MyMethod", new MemoryStream(), output).GetAwaiter().GetResult();
|
||||
await runtime.DispatchWithoutRemotingAsync("MyActor", "abc", "MyMethod", new MemoryStream(), output);
|
||||
string s = Encoding.UTF8.GetString(output.ToArray());
|
||||
|
||||
Assert.Equal("\"hi\"", s);
|
||||
Assert.Contains(actorType.Name, ActorRuntime.Instance.RegisteredActorTypes, StringComparer.InvariantCulture);
|
||||
Assert.Equal("\"hi\"", s);
|
||||
Assert.Contains(actorType.Name, runtime.RegisteredActorTypes, StringComparer.InvariantCulture);
|
||||
Console.WriteLine("done");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue