New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Co-hosted and Service Fabric #6961
Comments
Hi @StephaneMartignier, in your case, you have two DI containers: one for ASP.NET and one for Orleans. If you want, you can use the .NET Generic Host and host Orleans and ASP.NET in the same container/host. You configure Orleans by calling the You would create a Service Fabric statefull/stateless service listener which creates/starts/stops/disposes that host builder. To be clear, you would not need the Orleans Service Fabric integration package with that approach. One of the internal Orleans + Service Fabric services adopts that approach, and I find it preferable. |
Hi @ReubenBond, Thanks for the answer. Have you any code sample that I can take a look at for better understanding? |
You can certainly host a service built with the .NET Generic Host inside a Service Fabric service. Here are some code snippets that you could fix up and use yourself (and maybe other people on that Service Fabric thread would find them useful, too): /// <summary>
/// Service Fabric <see cref="ICommunicationListener"/> which integrates with an <see cref="IHost"/> instance.
/// </summary>
internal class HostedServiceCommunicationListener : ICommunicationListener
{
private readonly Func<Task<IHost>> _createHost;
private IHost _host;
public HostedServiceCommunicationListener(Func<Task<IHost>> createHost)
{
_createHost = createHost ?? throw new ArgumentNullException(nameof(createHost));
}
/// <inheritdoc />
public async Task<string> OpenAsync(CancellationToken cancellationToken)
{
try
{
_host = await _createHost();
await _host.StartAsync(cancellationToken);
}
catch
{
Abort();
throw;
}
// This service does not expose any endpoints to Service Fabric for discovery by others.
return null;
}
/// <inheritdoc />
public async Task CloseAsync(CancellationToken cancellationToken)
{
IHost host = _host;
if (host is object)
{
await host.StopAsync(cancellationToken);
}
_host = null;
}
/// <inheritdoc />
public void Abort()
{
IHost host = _host;
if (host is null)
{
return;
}
var cancellation = new CancellationTokenSource();
cancellation.Cancel(false);
try
{
host.StopAsync(cancellation.Token).GetAwaiter().GetResult();
}
catch
{
// Ignore.
}
finally
{
_host = null;
}
}
} In your public class MyStatelessService : StatelessService
{
protected MyStatelessService(StatelessServiceContext serviceContext) : base(serviceContext)
{
}
private async Task<IHost> CreateHostAsync(StatelessServiceContext serviceContext)
{
try
{
IHostBuilder hostBuilder = new HostBuilder();
hostBuilder.UseEnvironment(this.EnvironmentName);
hostBuilder.UseOrleans(siloBuilder => /* */);
// Since the Web service depends on the silo being started, add it after the silo.
// This ensures that the silo is started completely before starting the Web service.
hostBuilder.ConfigureServices(
services =>
{
// Configure a grace period for host shutdown.
services.Configure<HostOptions>(options => options.ShutdownTimeout = TimeSpan.FromMinutes(2));
// Report service health to Service Fabric in the background
services.AddSingleton<IHostedService>(serviceProvider => /* ... */);
});
// Configure ASP.NET
hostBuilder.ConfigureWebDefaults(/* */);
return hostBuilder.Build();
}
catch (Exception e)
{
// Log and throw
throw;
}
}
protected sealed override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
// Create a listener which creates and runs an IHost
yield return new ServiceInstanceListener(
context => new HostedServiceCommunicationListener(
() => this.CreateHostAsync(context),
"HostedServiceListener"));
}
} |
Hi, thanks for the code :) Unfortunately I won't have the time to dig into before next week due to others priorities popping up I will reach back to you on this thread when I've done some work on it Thanks again |
@StephaneMartignier Where you able to get this to work. I tried using @ReubenBond code snippet also but I could not get it work |
Hi @wusi2cool, I wasn't able to get this to work, I was on more urgent work and also on some vacations |
@wusi2cool what issues are you hitting? |
@ReubenBond This is the configuration I am using. I cannot reach the application when using this configuration. My knowledge of service fabric is limited, so I am pretty sure I must have done something wrong.
|
Are you configuring endpoints in Service Fabric? See an example here: Line 32 in 47495e6
You would then need to read the port numbers from those endpoints and configure your silo with them. I don't see any call to |
We are marking this issue as stale due to the lack of activity in the past six months. If there is no further activity within two weeks, this issue will be closed. You can always create a new issue based on the guidelines provided in our pinned announcement. |
This issue has been marked stale for the past 30 and is being closed due to lack of activity. |
Hi everyone,
So I'm interested to use the co-hosted client but with Service Fabric.
So fare we have a web api as Stateless Service on Service Fabric. We have configured it based on this documentation.
Then we configure the client in the ConfigureServices of the Startup
Basically all that our API is doing is offer entry point as controller and calling grain like
From what we understood of the documentation we are in the case where the co-hosted client can be used, but we are unable to configure it and we can't find any documentation on how to do it. Is it impossible to use the co-hosted client with ServiceFabric?
Thanks a lot
The text was updated successfully, but these errors were encountered: