OrleansContrib / SignalR.Orleans

SignalR backend based on Orleans.
MIT License
295 stars 64 forks source link

SignalR.Orleans 7.0.1 throws an exception with Microsoft.Orleans 7.1.0 #149

Closed EdoardoTona closed 1 year ago

EdoardoTona commented 1 year ago

SignalR.Orleans 7.0.1 throws the following exception with Microsoft.Orleans 7.1.0:

System.TypeLoadException: Could not load type 'Orleans.Serialization.Codecs.TagDelimitedFieldCodec' from assembly 'Orleans.Serialization, Version=7.0.0.0, Culture=neutral, PublicKeyToken=null'.
   at Orleans.Serialization.Serializer`1.SerializeToArray(T value) in /_/src/Orleans.Serialization/Serializer.cs:line 548
   at Orleans.Providers.DefaultMemoryMessageBodySerializer.Serialize(MemoryMessageBody body) in /_/src/Orleans.Streaming/MemoryStreams/MemoryMessageBody.cs:line 52
   at Orleans.Providers.MemoryAdapterFactory`1.QueueMessageBatchAsync[T](StreamId streamId, IEnumerable`1 events, StreamSequenceToken token, Dictionary`2 requestContext) in /_/src/Orleans.Streaming/MemoryStreams/MemoryAdapterFactory.cs:line 159
   at SignalR.Orleans.Clients.ClientGrain.Send(InvocationMessage message)
   at Orleans.Runtime.TaskRequest.Invoke() in /_/src/Orleans.Core.Abstractions/Runtime/GrainReference.cs:line 690
--- End of stack trace from previous location ---
   at Orleans.Serialization.Invocation.ResponseCompletionSource.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token) in /_/src/Orleans.Serialization/Invocation/ResponseCompletionSource.cs:line 98
   at System.Threading.Tasks.ValueTask.ValueTaskSourceAsTask.<>c.<.cctor>b__4_0(Object state)
--- End of stack trace from previous location ---
   at Orleans.Runtime.TaskRequest.CompleteInvokeAsync(Task resultTask) in /_/src/Orleans.Core.Abstractions/Runtime/GrainReference.cs:line 707
   at Orleans.Serialization.Invocation.ResponseCompletionSource.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token) in /_/src/Orleans.Serialization/Invocation/ResponseCompletionSource.cs:line 98
   at System.Threading.Tasks.ValueTask.ValueTaskSourceAsTask.<>c.<.cctor>b__4_0(Object state)
--- End of stack trace from previous location ---
   at Orleans.Runtime.TaskRequest.CompleteInvokeAsync(Task resultTask) in /_/src/Orleans.Core.Abstractions/Runtime/GrainReference.cs:line 707
   at Orleans.Serialization.Invocation.ResponseCompletionSource.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token) in /_/src/Orleans.Serialization/Invocation/ResponseCompletionSource.cs:line 98
   at System.Threading.Tasks.ValueTask.ValueTaskSourceAsTask.<>c.<.cctor>b__4_0(Object state)
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

Using Orleans 7.0.0 it works fine.

How to reproduce the exception

Test.csproj:

<Project Sdk="Microsoft.NET.Sdk.Web">

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

  <ItemGroup>

    <PackageReference Include="Microsoft.Orleans.Server" Version="7.1.0" />
    <PackageReference Include="SignalR.Orleans" Version="7.0.1" />
  </ItemGroup>

</Project>

Program.cs:

using Microsoft.AspNetCore.SignalR;

var builder = WebApplication.CreateBuilder(args);
builder.Host.UseOrleans(siloBuilder =>
{
  siloBuilder.UseLocalhostClustering();
  siloBuilder.UseSignalR();
  siloBuilder.RegisterHub<MyHub>();
});

builder.Services
      .AddCors();

builder.Services
    .AddSignalR()
    .AddOrleans();

var app = builder.Build();

app.UseCors(x => x
        .AllowAnyMethod()
        .AllowAnyHeader()
        .SetIsOriginAllowed(origin => true)
        .AllowCredentials());

app.MapHub<MyHub>("/myhub");

app.MapGet("/send", httpContext =>
  httpContext.RequestServices
            .GetRequiredService<IGrainFactory>()
            .GetGrain<IMyGrain>("id")
            .Send("test")
);

await app.RunAsync();

class MyHub : Hub { }

interface IMyGrain : IGrainWithStringKey
{
  Task Send(string msg);
}
class MyGrain : Grain, IMyGrain
{
  readonly IHubContext<MyHub> _hub;
  public MyGrain(IHubContext<MyHub> hubContext)
    => _hub = hubContext;

  public Task Send(string msg) =>
    _hub.Clients.All.SendCoreAsync("msg", new[] { msg });
}

I think updating the internal references to the latest Orleans should be enougth to fix this issue.

EdoardoTona commented 1 year ago

Related: https://github.com/OrleansContrib/OrleansDashboard/issues/389

galvesribeiro commented 1 year ago

Thanks for the report and fix. It is released on https://www.nuget.org/packages/SignalR.Orleans/7.1.0.

EdoardoTona commented 1 year ago

Thanks for the merging, I can confirm the nuget 7.1.0 is working as expected