Skip to content

Instantly share code, notes, and snippets.

@ReubenBond
Last active December 1, 2022 21:10
Show Gist options
  • Save ReubenBond/83a08cfdc77d6232f97ec531e377fdc4 to your computer and use it in GitHub Desktop.
Save ReubenBond/83a08cfdc77d6232f97ec531e377fdc4 to your computer and use it in GitHub Desktop.
Service Fabric IHostBuilder integration
namespace YOUR_NAMESPACE
{
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.ServiceFabric.Services.Communication.Runtime;
/// <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;
/// <summary>
/// Initializes a new instance of the <see cref="CommunicationListener" /> class.
/// </summary>
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;
}
}
}
}
namespace YOUR_NAMESPACE
{
using System.Collections.Generic;
using System.Fabric;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.ServiceFabric.Services.Communication.Runtime;
using Microsoft.ServiceFabric.Services.Runtime;
public abstract class HostedServiceStatelessService : StatelessService
{
protected abstract string ServiceName { get; }
private const string HttpsEndpointConfigName = "HttpsEndpoint";
protected int HttpsPort => GetPortFromManifest(HttpsEndpointConfigName);
protected HostedServiceStatelessService(StatelessServiceContext serviceContext) : base(serviceContext)
{
}
protected int GetPortFromManifest(string portName)
{
return Context.CodePackageActivationContext.GetEndpoint(portName).Port;
}
protected abstract Task<IHost> CreateHostAsync(StatelessServiceContext context);
/// <inheritdoc/>
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");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment