dotnet / orleans

Cloud Native application framework for .NET
https://docs.microsoft.com/dotnet/orleans
MIT License
10.06k stars 2.03k forks source link

F# host: Could not find an implementation for interface OrleansDashboard.IDashboardGrain - C# host ok #8235

Open fwaris opened 1 year ago

fwaris commented 1 year ago

Unable to host silo in F# console project. C# console project works fine. Please see attached minimal repo.

FsGrains (2).zip

Need to host in F# due to other F# frameworks (e.g. for web dev) required for the application.

Issue is with the 7.x version. This was not an issue with the 3.x.x version of Orleans.

F# hosting works if 'UseDashboard' is commented out.

Error seen:

fail: Orleans.Runtime.SiloLifecycleSubject[100450]
      Orleans.Hosting.SiloBuilderStartupExtensions+StartupTask failed to start due to errors at stage Active (20000)
      System.ArgumentException: Could not find an implementation for interface OrleansDashboard.IDashboardGrain
         at Orleans.GrainInterfaceTypeToGrainTypeResolver.GetGrainType(GrainInterfaceType interfaceType) in /_/src/Orleans.Core/Core/GrainInterfaceTypeToGrainTypeResolver.cs:line 149
         at Orleans.GrainFactory.GetGrain(Type interfaceType, IdSpan grainKey, String grainClassNamePrefix) in /_/src/Orleans.Core/Core/GrainFactory.cs:line 214
         at Orleans.GrainFactory.GetGrain[TGrainInterface](Int64 primaryKey, String grainClassNamePrefix) in /_/src/Orleans.Core/Core/GrainFactory.cs:line 52
         at OrleansDashboard.Dashboard.ActivateDashboardGrainAsync()
         at OrleansDashboard.Dashboard.Execute(CancellationToken cancellationToken)
         at Orleans.Runtime.SiloLifecycleSubject.MonitoredObserver.OnStart(CancellationToken ct) in /_/src/Orleans.Runtime/Lifecycle/SiloLifecycleSubject.cs:line 134
f
fwaris commented 1 year ago

Update: I set <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> in the C# host project and found that there are 'generated' files for Dashboard grain serialization.

No source is generated for F# so maybe that's the reason for the error. However, not sure what is the solution other than maybe support for F# code generation.

fwaris commented 1 year ago

After a little more digging, I found that adding parts of C# generated code - namely assembly attributes - to F# host, fixed this issue. 'Program.fs' is now as follows:

open Microsoft.Extensions.Hosting
open Orleans
open Orleans.Hosting

Host.CreateDefaultBuilder()
    .UseOrleans(fun siloBuilder -> 
        siloBuilder
          .UseDashboard()
          .UseLocalhostClustering() 
          .AddMemoryGrainStorage("store") |> ignore)
    .RunConsoleAsync()
|> Async.AwaitTask
|> Async.RunSynchronously

module Load =

    //[<assembly: Orleans.ApplicationPartAttribute("SiloCS")>]
    [<assembly: Orleans.ApplicationPartAttribute("GrainsCodeGen")>]
    [<assembly: Orleans.ApplicationPartAttribute("Orleans.Core.Abstractions")>]
    [<assembly: Orleans.ApplicationPartAttribute("Orleans.Serialization")>]
    [<assembly: Orleans.ApplicationPartAttribute("Orleans.Core")>]
    [<assembly: Orleans.ApplicationPartAttribute("Orleans.Persistence.Memory")>]
    [<assembly: Orleans.ApplicationPartAttribute("Orleans.Runtime")>]
    [<assembly: Orleans.ApplicationPartAttribute("Orleans.Reminders")>]
    [<assembly: Orleans.ApplicationPartAttribute("OrleansDashboard.Core")>]
    [<assembly: Orleans.ApplicationPartAttribute("OrleansDashboard")>]
    //[<assembly: global::Orleans.Serialization.Configuration.TypeManifestProviderAttribute(typeof(OrleansCodeGen.SiloCS.Metadata_SiloCS))]
    ()

I will use this as a workaround while waiting for the 'official' fix or recommendation.

Also not sure what the TypeManifestProvider attribute does and will a lack of it cause issues later on?

fwaris commented 1 year ago

linking reminders issue #8125. The workaround solution will likely work for the reminder table issue also

WesleySkeen commented 1 year ago

Thanks legend. Nice one for this