I have a .NET Core Reliable Service that is pretty much a template service, obtained from the Add > New Service Fabric Service > .NET Core Stateless Service. This means that it contains the ServiceEventSource, a Stateless1 class that inherits from the StatelessService class, and a Program.cs. The contents of the Program.cs are the default ones:
private static void Main()
{
try
{
ServiceRuntime.RegisterServiceAsync("Stateless1Type",
context => new Stateless1(context)).GetAwaiter().GetResult(); ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(Stateless1).Name);
Thread.Sleep(Timeout.Infinite);
}
catch (Exception e)
{ ServiceEventSource.Current.ServiceHostInitializationFailed(e.ToString());
throw;
}
}
Now, this is working fine, I am able to start the Service Fabric application correctly and see logs, etc.
What I am trying to accomplish is to containerize this service, as per the following article: https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-services-inside-containers . This means that I added the SFBinaryLoader.cs and added the following file to my Program.cs:
static Program()
{
SFBinaryLoader.Initialize();
}
However, by trying this a lot of questions and problems arise which aren't addressed by the documentation.
I am using the microsoft/service-fabric-reliableservices-windowsservercore:1803 as a base image to build my container. This, since the windows server host is version 1803. After running the CreateDockerPackage.ps1 I notice that the Microsoft.ServiceFabric.Data.Interfaces.dll and the System.Fabric.*.dll are being removed.
I think this is why we must be supplied again on runtime. This is performed by the SFBinaryLoader.cs by adding an event listener on the AppDomain.CurrentDomain.AssemblyResolve. This class should look at the FabricCodePath environment variable (which on runtime looks to be binding to the C:\SFFabricBin\ directory) and manually add those binaries.
I would say that in order for the program to run, I had to also remove the *.deps.json file from the container, because I was getting an exception before even running the dotnet Stateless1.dll stating that some missing binaries declared on the *.deps.json file were not found.
Now, it looks like my container is starting up fine by the fabric, and that assemblies are being correctly loaded. However, whenever trying to register the service to the fabric by the following line:
ServiceRuntime.RegisterServiceAsync("Stateless1Type",
context => new Stateless1(context)).GetAwaiter().GetResult();
This throws the following exception:
An exception occurred registering the service System.Fabric.FabricException: Service Type is already registered. ---> System.Runtime.InteropServices.COMException: Exception from HRESULT: 0x80071BD1 at System.Fabric.Interop.NativeRuntime.IFabricRuntime.EndRegisterStatelessServiceFactory(IFabricAsyncOperationContext context) at System.Fabric.Interop.Utility.<>c__DisplayClass22_0.b__0(IFabricAsyncOperationContext context) at System.Fabric.Interop.AsyncCallOutAdapter2
1.Finish(IFabricAsyncOperationContext context, Boolean expectedCompletedSynchronously) --- End of inner exception stack trace --- at Microsoft.ServiceFabric.Services.Runtime.ServiceRuntime.RegisterServiceAsync(String serviceTypeName, Func2 serviceFactory, TimeSpan timeout, CancellationToken cancellationToken) at Eventellect.Fabric.TestDocker.Program.Main() in C:\MyLocalPath\StatelessService\Program.cs:line 33
Do you know why is this happening? I also find it very weird that somehow my published service fabric knows anything at all about my local path.
I have already surrounded the RegisterServiceAsync call inside a try...catch block, but then, even though the thread goes to sleep succesfully and my docker container does not stop, actions inside my Stateless1.cs class are never performed. This means that not even the constructor is invoked.
Is there something I might be missing?