Skip to content
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

Implement generic host #934

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
2 changes: 2 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
<PackageVersion Include="JsonPath.Net" Version="1.1.6" />
<PackageVersion Include="KeraLua" Version="1.4.1" />
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
<PackageVersion Include="NUnit" Version="4.1.0" />
<PackageVersion Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageVersion Include="Microsoft.CodeAnalysis" Version="4.11.0" />
Expand Down
3 changes: 2 additions & 1 deletion benchmark/BDN.benchmark/Embedded/EmbeddedRespServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ internal sealed class EmbeddedRespServer : GarnetServer
/// <param name="opts">Server options to configure the base GarnetServer instance</param>
/// <param name="loggerFactory">Logger factory to configure the base GarnetServer instance</param>
/// <param name="server">Server network</param>
public EmbeddedRespServer(GarnetServerOptions opts, ILoggerFactory loggerFactory = null, GarnetServerEmbedded server = null) : base(opts, loggerFactory, server)
public EmbeddedRespServer(GarnetServerOptions opts, ILoggerFactory loggerFactory = null, GarnetServerEmbedded server = null)
: base(opts, loggerFactory, server)
{
this.garnetServerEmbedded = server;
}
Expand Down
15 changes: 4 additions & 11 deletions hosting/Windows/Garnet.worker/Worker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Garnet.host;
using Microsoft.Extensions.Hosting;

namespace Garnet
Expand All @@ -22,19 +23,11 @@ public Worker(string[] args)

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
server = new GarnetServer(args);
var builder = GarnetApplication.CreateHostBuilder(args);

// Start the server
server.Start();
var app = builder.Build();

await Task.Delay(Timeout.Infinite, stoppingToken).ConfigureAwait(false);
}
catch (Exception ex)
{
Console.WriteLine($"Unable to initialize server due to exception: {ex.Message}");
}
await app.RunAsync(stoppingToken);
}

/// <summary>
Expand Down
30 changes: 18 additions & 12 deletions libs/cluster/ClusterFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,25 @@
using Microsoft.Extensions.Logging;
using Tsavorite.core;

namespace Garnet.cluster
namespace Garnet.cluster;

/// <summary>
/// Cluster factory
/// </summary>
public class ClusterFactory : IClusterFactory
{
/// <summary>
/// Cluster factory
/// </summary>
public class ClusterFactory : IClusterFactory
private readonly ILogger<ClusterFactory> logger;

public ClusterFactory(ILogger<ClusterFactory> logger)
{
/// <inheritdoc />
public DeviceLogCommitCheckpointManager CreateCheckpointManager(INamedDeviceFactory deviceFactory, ICheckpointNamingScheme checkpointNamingScheme, bool isMainStore, ILogger logger = default)
=> new ReplicationLogCheckpointManager(deviceFactory, checkpointNamingScheme, isMainStore, logger: logger);

/// <inheritdoc />
public IClusterProvider CreateClusterProvider(StoreWrapper store)
=> new ClusterProvider(store);
this.logger = logger;
}

/// <inheritdoc />
public DeviceLogCommitCheckpointManager CreateCheckpointManager(INamedDeviceFactory deviceFactory, ICheckpointNamingScheme checkpointNamingScheme, bool isMainStore)
=> new ReplicationLogCheckpointManager(deviceFactory, checkpointNamingScheme, isMainStore, logger: logger);

/// <inheritdoc />
public IClusterProvider CreateClusterProvider(StoreWrapper store)
=> new ClusterProvider(store);
}
13 changes: 7 additions & 6 deletions libs/cluster/Server/ClusterProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ public class ClusterProvider : IClusterProvider
internal readonly ReplicationManager replicationManager;
internal readonly FailoverManager failoverManager;
internal readonly MigrationManager migrationManager;
internal readonly ILoggerFactory loggerFactory;
internal readonly StoreWrapper storeWrapper;
internal readonly GarnetServerOptions serverOptions;
internal long GarnetCurrentEpoch = 1;
Expand All @@ -47,14 +46,16 @@ public class ClusterProvider : IClusterProvider
/// </summary>
public string ClusterPassword => authContainer.ClusterPassword;

public ILogger logger;

/// <summary>
/// Create new cluster provider
/// </summary>
public ClusterProvider(StoreWrapper storeWrapper)
{
this.storeWrapper = storeWrapper;
this.serverOptions = storeWrapper.serverOptions;
this.loggerFactory = storeWrapper.loggerFactory;
this.logger = storeWrapper.logger;

authContainer = new ClusterAuthContainer
{
Expand All @@ -67,11 +68,11 @@ public ClusterProvider(StoreWrapper storeWrapper)
throw new Exception("Gossip sample fraction should be in range [0,100]");
}

this.clusterManager = new ClusterManager(this, logger: loggerFactory?.CreateLogger("ClusterManager"));
this.replicationManager = new ReplicationManager(this, logger: loggerFactory?.CreateLogger("ReplicationManager"));
this.clusterManager = new ClusterManager(this, logger: logger);
this.replicationManager = new ReplicationManager(this, logger: logger);

this.failoverManager = new FailoverManager(this, logger: loggerFactory?.CreateLogger("FailoverManager"));
this.migrationManager = new MigrationManager(this, logger: loggerFactory?.CreateLogger("MigrationManager"));
this.failoverManager = new FailoverManager(this, logger: logger);
this.migrationManager = new MigrationManager(this, logger: logger);
}

/// <inheritdoc />
Expand Down
3 changes: 2 additions & 1 deletion libs/cluster/Server/Migration/MigrateSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ internal MigrateSession(
MigratingKeysWorkingSet keys,
TransferOption transferOption)
{
this.logger = clusterProvider.loggerFactory.CreateLogger($"MigrateSession - {GetHashCode()}"); ;
//this.logger = clusterProvider.loggerFactory.CreateLogger($"MigrateSession - {GetHashCode()}"); ;
this.logger = clusterProvider.logger;
this.clusterSession = clusterSession;
this.clusterProvider = clusterProvider;
this._targetAddress = _targetAddress;
Expand Down
4 changes: 3 additions & 1 deletion libs/host/Garnet.host.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
<PackageReference Include="Microsoft.Extensions.Hosting" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" />
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
<PackageReference Include="CommandLineParser" />
<PackageReference Include="Microsoft.Extensions.Logging" />
Expand All @@ -43,5 +46,4 @@
<Content Include="..\host\bin\Release\net8.0\runtimes\**\*.dll" Pack="true" PackagePath="runtimes" />
<None Include="..\..\README.md" Pack="true" PackagePath="/"/>
</ItemGroup>

</Project>
77 changes: 77 additions & 0 deletions libs/host/GarnetApplication.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

using System;
using System.Threading;
using System.Threading.Tasks;
using Garnet.common;
using Garnet.server;
using Microsoft.Extensions.Hosting;

namespace Garnet.host;

/// <summary>
///
/// </summary>
public class GarnetApplication : IHost
{
private readonly IHost host;

public GarnetApplication(IHost host)
{
this.host = host;
}

public IServiceProvider Services => host.Services;

public Task StartAsync(CancellationToken cancellationToken = default)
=> host.StartAsync(cancellationToken);

public Task StopAsync(CancellationToken cancellationToken = default)
=> host.StopAsync(cancellationToken);

public void Dispose() => host.Dispose();

public void Run()
{
HostingAbstractionsHostExtensions.Run(this);
}

public async Task RunAsync(CancellationToken cancellationToken = default)
{
await HostingAbstractionsHostExtensions.RunAsync(this, cancellationToken);
}

public static GarnetApplicationBuilder CreateHostBuilder(string[] args)
{
MemoryLogger initLogger;

// Set up an initial memory logger to log messages from configuration parser into memory.
using (var memLogProvider = new MemoryLoggerProvider())
{
initLogger = (MemoryLogger)memLogProvider.CreateLogger("ArgParser");
}

if (!ServerSettingsManager.TryParseCommandLineArguments(args, out var serverSettings, out _,
out var exitGracefully, initLogger))
{
if (exitGracefully)
System.Environment.Exit(0);

// Flush logs from memory logger
//FlushMemoryLogger(this.initLogger, "ArgParser");

throw new GarnetException(
"Encountered an error when initializing Garnet server. Please see log messages above for more details.");
}

var garnetServerOptions = serverSettings.GetServerOptions(null);

return new (new GarnetApplicationOptions {Args = args}, garnetServerOptions);
}

public static GarnetApplicationBuilder CreateHostBuilder(string[] args, GarnetServerOptions options)
{
return new (new GarnetApplicationOptions {Args = args}, options);
}
}
Loading