Skip to content

Commit 4b55f59

Browse files
committed
move more of the initialization code out of GarnetServer constructor
1 parent d7c37bf commit 4b55f59

File tree

7 files changed

+127
-91
lines changed

7 files changed

+127
-91
lines changed

benchmark/BDN.benchmark/Embedded/EmbeddedRespServer.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Garnet;
55
using Garnet.server;
66
using Microsoft.Extensions.Logging;
7+
using Microsoft.Extensions.Options;
78

89
namespace Embedded.server
910
{
@@ -18,10 +19,15 @@ internal sealed class EmbeddedRespServer : GarnetServer
1819
/// Creates an EmbeddedRespServer instance
1920
/// </summary>
2021
/// <param name="opts">Server options to configure the base GarnetServer instance</param>
21-
/// <param name="loggerFactory">Logger factory to configure the base GarnetServer instance</param>
22+
/// <param name="logger">Logger factory to configure the base GarnetServer instance</param>
2223
/// <param name="server">Server network</param>
23-
public EmbeddedRespServer(GarnetServerOptions opts, ILoggerFactory loggerFactory = null, GarnetServerEmbedded server = null)
24-
: base(opts, loggerFactory, server)
24+
/// <param name="store">Server network</param>
25+
public EmbeddedRespServer(
26+
IOptions<GarnetServerOptions> opts,
27+
ILogger<GarnetServer> logger,
28+
GarnetServerEmbedded server,
29+
StoreWrapper store)
30+
: base(opts, logger, server, store)
2531
{
2632
this.garnetServerEmbedded = server;
2733
}

benchmark/BDN.benchmark/Lua/LuaRunnerOperations.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using BenchmarkDotNet.Attributes;
55
using Embedded.server;
6+
using Garnet.host;
67
using Garnet.server;
78

89
namespace BDN.benchmark.Lua
@@ -154,6 +155,14 @@ public IEnumerable<LuaParams> LuaParamsProvider()
154155
[GlobalSetup]
155156
public void GlobalSetup()
156157
{
158+
var builder = GarnetApplication.CreateHostBuilder([], new GarnetServerOptions()
159+
{
160+
EnableLua = true,
161+
QuietMode = true
162+
});
163+
164+
var app = builder.Build();
165+
157166
server = new EmbeddedRespServer(new GarnetServerOptions() { EnableLua = true, QuietMode = true });
158167

159168
session = server.GetRespSession();

hosting/Windows/Garnet.worker/Program.cs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,13 @@
55
using Microsoft.Extensions.DependencyInjection;
66
using Microsoft.Extensions.Hosting;
77

8-
class Program
9-
{
10-
static void Main(string[] args)
11-
{
12-
var builder = Host.CreateApplicationBuilder(args);
13-
builder.Services.AddHostedService(_ => new Worker(args));
8+
var builder = Host.CreateApplicationBuilder(args);
9+
builder.Services.AddHostedService(_ => new Worker(args));
1410

15-
builder.Services.AddWindowsService(options =>
16-
{
17-
options.ServiceName = "Microsoft Garnet Server";
18-
});
11+
builder.Services.AddWindowsService(options =>
12+
{
13+
options.ServiceName = "Microsoft Garnet Server";
14+
});
1915

20-
var host = builder.Build();
21-
host.Run();
22-
}
23-
}
16+
var host = builder.Build();
17+
host.Run();

libs/host/GarnetApplication.cs

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
// Licensed under the MIT license.
33

44
using System;
5+
using System.Diagnostics;
6+
using System.Reflection;
57
using System.Threading;
68
using System.Threading.Tasks;
79
using Garnet.common;
810
using Garnet.server;
11+
using Microsoft.Extensions.DependencyInjection;
912
using Microsoft.Extensions.Hosting;
13+
using Microsoft.Extensions.Logging;
14+
using Microsoft.Extensions.Options;
1015

1116
namespace Garnet.host;
1217

@@ -25,7 +30,53 @@ public GarnetApplication(IHost host)
2530
public IServiceProvider Services => host.Services;
2631

2732
public Task StartAsync(CancellationToken cancellationToken = default)
28-
=> host.StartAsync(cancellationToken);
33+
{
34+
var opts = host.Services.GetRequiredService<IOptions<GarnetServerOptions>>();
35+
var logger = host.Services.GetRequiredService<ILogger<GarnetServer>>();
36+
37+
Debug.Assert(opts != null);
38+
39+
var version = GetVersion();
40+
41+
if (!opts.Value.QuietMode)
42+
{
43+
var red = "\u001b[31m";
44+
var magenta = "\u001b[35m";
45+
var normal = "\u001b[0m";
46+
47+
Console.WriteLine($@"{red} _________
48+
/_||___||_\ {normal}Garnet {version} {(IntPtr.Size == 8 ? "64" : "32")} bit; {(opts.Value.EnableCluster ? "cluster" : "standalone")} mode{red}
49+
'. \ / .' {normal}Port: {opts.Value.Port}{red}
50+
'.\ /.' {magenta}https://aka.ms/GetGarnet{red}
51+
'.'
52+
{normal}");
53+
}
54+
55+
Trace.Listeners.Add(new ConsoleTraceListener());
56+
57+
// Set up an initial memory logger to log messages from configuration parser into memory.
58+
using var memLogProvider = new MemoryLoggerProvider();
59+
60+
var initLogger = (MemoryLogger)memLogProvider.CreateLogger("ArgParser");
61+
62+
logger?.LogInformation("Garnet {version} {bits} bit; {clusterMode} mode; Port: {port}", GetVersion(), IntPtr.Size == 8 ? "64" : "32", opts.Value.EnableCluster ? "cluster" : "standalone", opts.Value.Port);
63+
64+
// Flush initialization logs from memory logger
65+
initLogger.FlushLogger(logger);
66+
67+
var setMax = opts.Value.ThreadPoolMaxThreads <= 0 || ThreadPool.SetMaxThreads(opts.Value.ThreadPoolMaxThreads, opts.Value.ThreadPoolMaxThreads);
68+
69+
if (opts.Value.ThreadPoolMinThreads > 0 && !ThreadPool.SetMinThreads(opts.Value.ThreadPoolMinThreads, opts.Value.ThreadPoolMinThreads))
70+
throw new Exception($"Unable to call ThreadPool.SetMinThreads with {opts.Value.ThreadPoolMinThreads}");
71+
72+
// Retry to set max threads if it wasn't set in the previous step
73+
if (!setMax && !ThreadPool.SetMaxThreads(opts.Value.ThreadPoolMaxThreads, opts.Value.ThreadPoolMaxThreads))
74+
throw new Exception($"Unable to call ThreadPool.SetMaxThreads with {opts.Value.ThreadPoolMaxThreads}");
75+
76+
logger?.LogTrace("TLS is {tlsEnabled}", opts.Value.TlsOptions == null ? "disabled" : "enabled");
77+
78+
return host.StartAsync(cancellationToken);
79+
}
2980

3081
public Task StopAsync(CancellationToken cancellationToken = default)
3182
=> host.StopAsync(cancellationToken);
@@ -59,7 +110,7 @@ public static GarnetApplicationBuilder CreateHostBuilder(string[] args)
59110
System.Environment.Exit(0);
60111

61112
// Flush logs from memory logger
62-
//FlushMemoryLogger(this.initLogger, "ArgParser");
113+
//initLogger.FlushLogger(logger);
63114

64115
throw new GarnetException(
65116
"Encountered an error when initializing Garnet server. Please see log messages above for more details.");
@@ -74,4 +125,10 @@ public static GarnetApplicationBuilder CreateHostBuilder(string[] args, GarnetSe
74125
{
75126
return new (new GarnetApplicationOptions {Args = args}, options);
76127
}
128+
129+
private static string GetVersion()
130+
{
131+
var Version = Assembly.GetExecutingAssembly().GetName().Version;
132+
return $"{Version.Major}.{Version.Minor}.{Version.Build}";
133+
}
77134
}

libs/host/GarnetApplicationBuilder.cs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,6 @@ public class GarnetApplicationBuilder : IHostApplicationBuilder
3030

3131
internal GarnetApplicationBuilder(GarnetApplicationOptions options, GarnetServerOptions garnetServerOptions)
3232
{
33-
var version = GetVersion();
34-
35-
if (!garnetServerOptions.QuietMode)
36-
{
37-
var red = "\u001b[31m";
38-
var magenta = "\u001b[35m";
39-
var normal = "\u001b[0m";
40-
41-
Console.WriteLine($@"{red} _________
42-
/_||___||_\ {normal}Garnet {version} {(IntPtr.Size == 8 ? "64" : "32")} bit; {(garnetServerOptions.EnableCluster ? "cluster" : "standalone")} mode{red}
43-
'. \ / .' {normal}Port: {garnetServerOptions.Port}{red}
44-
'.\ /.' {magenta}https://aka.ms/GetGarnet{red}
45-
'.'
46-
{normal}");
47-
}
48-
4933
var configuration = new ConfigurationManager();
5034

5135
configuration.AddEnvironmentVariables(prefix: "GARNET_");
@@ -72,13 +56,13 @@ internal GarnetApplicationBuilder(GarnetApplicationOptions options, GarnetServer
7256
var garnetServerOptionsWrapped = Microsoft.Extensions.Options.Options.Create(garnetServerOptions);
7357
hostApplicationBuilder.Services.AddSingleton(garnetServerOptionsWrapped);
7458

75-
hostApplicationBuilder.Services.AddSingleton<GarnetServerTcp>();
59+
hostApplicationBuilder.Services.AddSingleton<IGarnetServer, GarnetServerTcp>();
7660
hostApplicationBuilder.Services.AddSingleton<StoreFactory>();
7761
hostApplicationBuilder.Services.AddSingleton<CustomCommandManager>();
7862

7963
hostApplicationBuilder.Services.AddSingleton(sp =>
8064
{
81-
var server = sp.GetRequiredService<GarnetServerTcp>();
65+
var server = sp.GetRequiredService<IGarnetServer>();
8266
var opts = sp.GetRequiredService<IOptions<GarnetServerOptions>>();
8367
var customCommandManager = sp.GetRequiredService<CustomCommandManager>();
8468
var logger = sp.GetRequiredService<ILogger<StoreWrapper>>();
@@ -129,6 +113,28 @@ internal GarnetApplicationBuilder(GarnetApplicationOptions options, GarnetServer
129113
customCommandManager, appendOnlyFile, opts.Value, logger, clusterFactory: clusterFactory);
130114
});
131115

116+
if (!garnetServerOptions.DisablePubSub)
117+
{
118+
hostApplicationBuilder.Services
119+
.AddSingleton(sp =>
120+
{
121+
var opts = sp.GetRequiredService<IOptions<GarnetServerOptions>>();
122+
return SubscribeBroker<SpanByte, SpanByte, IKeySerializer<SpanByte>>.Create(opts);
123+
});
124+
}
125+
126+
hostApplicationBuilder.Services.AddSingleton(sp =>
127+
{
128+
var storeWrapper = sp.GetRequiredService<StoreWrapper>();
129+
var subscriberBroker = sp.GetService<SubscribeBroker<SpanByte, SpanByte, IKeySerializer<SpanByte>>>();
130+
131+
return new GarnetProvider(storeWrapper, subscriberBroker);
132+
});
133+
134+
hostApplicationBuilder.Services.AddSingleton<MetricsApi>();
135+
hostApplicationBuilder.Services.AddSingleton<RegisterApi>();
136+
hostApplicationBuilder.Services.AddSingleton<StoreApi>();
137+
132138
hostApplicationBuilder.Services.AddHostedService<GarnetServer>();
133139
}
134140

libs/host/GarnetServer.cs

Lines changed: 10 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ public class GarnetServer : IHostedService, IDisposable
2626
private readonly GarnetServerOptions opts;
2727
private IGarnetServer server;
2828
private SubscribeBroker<SpanByte, SpanByte, IKeySerializer<SpanByte>> subscribeBroker;
29-
private readonly MemoryLogger initLogger;
3029
private readonly ILogger<GarnetServer> logger;
3130

3231
/// <summary>
@@ -52,7 +51,7 @@ public class GarnetServer : IHostedService, IDisposable
5251
public GarnetServer(
5352
IOptions<GarnetServerOptions> opts,
5453
ILogger<GarnetServer> logger,
55-
GarnetServerTcp garnetServerTcp,
54+
IGarnetServer garnetServerTcp,
5655
StoreWrapper storeWrapper)
5756
{
5857
this.logger = logger;
@@ -61,53 +60,24 @@ public GarnetServer(
6160

6261
Trace.Listeners.Add(new ConsoleTraceListener());
6362

64-
// Set up an initial memory logger to log messages from configuration parser into memory.
65-
using (var memLogProvider = new MemoryLoggerProvider())
66-
{
67-
this.initLogger = (MemoryLogger)memLogProvider.CreateLogger("ArgParser");
68-
}
69-
7063
// Assign values to GarnetServerOptions
7164
this.opts = opts.Value;
7265
this.opts.AuthSettings = this.opts.AuthSettings;
66+
7367
this.InitializeServer();
7468
}
7569

7670
private void InitializeServer()
7771
{
78-
Debug.Assert(opts != null);
79-
80-
using (logger.BeginScope("GarnetServer"))
81-
{
82-
logger?.LogInformation("Garnet {version} {bits} bit; {clusterMode} mode; Port: {port}", GetVersion(), IntPtr.Size == 8 ? "64" : "32", opts.EnableCluster ? "cluster" : "standalone", opts.Port);
83-
84-
// Flush initialization logs from memory logger
85-
FlushMemoryLogger(this.initLogger, "ArgParser");
86-
87-
var setMax = opts.ThreadPoolMaxThreads <= 0 || ThreadPool.SetMaxThreads(opts.ThreadPoolMaxThreads, opts.ThreadPoolMaxThreads);
88-
89-
if (opts.ThreadPoolMinThreads > 0 && !ThreadPool.SetMinThreads(opts.ThreadPoolMinThreads, opts.ThreadPoolMinThreads))
90-
throw new Exception($"Unable to call ThreadPool.SetMinThreads with {opts.ThreadPoolMinThreads}");
91-
92-
// Retry to set max threads if it wasn't set in the previous step
93-
if (!setMax && !ThreadPool.SetMaxThreads(opts.ThreadPoolMaxThreads, opts.ThreadPoolMaxThreads))
94-
throw new Exception($"Unable to call ThreadPool.SetMaxThreads with {opts.ThreadPoolMaxThreads}");
95-
96-
if (!opts.DisablePubSub)
97-
subscribeBroker = new SubscribeBroker<SpanByte, SpanByte, IKeySerializer<SpanByte>>(new SpanByteKeySerializer(), null, opts.PubSubPageSizeBytes(), opts.SubscriberRefreshFrequencyMs, true);
72+
// Create session provider for Garnet
73+
Provider = new GarnetProvider(storeWrapper, subscribeBroker);
9874

99-
logger?.LogTrace("TLS is {tlsEnabled}", opts.TlsOptions == null ? "disabled" : "enabled");
75+
// Create user facing API endpoints
76+
Metrics = new MetricsApi(Provider);
77+
Register = new RegisterApi(Provider);
78+
Store = new StoreApi(storeWrapper);
10079

101-
// Create session provider for Garnet
102-
Provider = new GarnetProvider(storeWrapper, subscribeBroker);
103-
104-
// Create user facing API endpoints
105-
Metrics = new MetricsApi(Provider);
106-
Register = new RegisterApi(Provider);
107-
Store = new StoreApi(storeWrapper);
108-
109-
server.Register(WireFormat.ASCII, Provider);
110-
}
80+
server.Register(WireFormat.ASCII, Provider);
11181
}
11282

11383
/// <summary>
@@ -119,7 +89,7 @@ public void Start()
11989
server.Start();
12090
Provider.Start();
12191
if (!opts.QuietMode)
122-
Console.WriteLine("* Ready to accept connections");
92+
this.logger.LogInformation("* Ready to accept connections");
12393
}
12494

12595
/// <summary>
@@ -158,20 +128,6 @@ private void InternalDispose()
158128
opts.AuthSettings?.Dispose();
159129
}
160130

161-
/// <summary>
162-
/// Flushes MemoryLogger entries into a destination logger.
163-
/// Destination logger is either created from ILoggerFactory parameter or from a default console logger.
164-
/// </summary>
165-
/// <param name="memoryLogger">The memory logger</param>
166-
/// <param name="categoryName">The category name of the destination logger</param>
167-
private void FlushMemoryLogger(MemoryLogger memoryLogger, string categoryName)
168-
{
169-
using (this.logger.BeginScope(categoryName))
170-
{
171-
memoryLogger.FlushLogger(this.logger);
172-
}
173-
}
174-
175131
public Task StartAsync(CancellationToken cancellationToken)
176132
{
177133
Start();

libs/server/PubSub/SubscribeBroker.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Threading.Tasks;
1111
using Garnet.common;
1212
using Garnet.networking;
13+
using Microsoft.Extensions.Options;
1314
using Tsavorite.core;
1415

1516
namespace Garnet.server
@@ -35,6 +36,13 @@ public sealed class SubscribeBroker<TKey, TValue, TKeyValueSerializer> : IDispos
3536
readonly ManualResetEvent done = new(true);
3637
bool disposed = false;
3738

39+
public static SubscribeBroker<SpanByte, SpanByte, IKeySerializer<SpanByte>> Create(
40+
IOptions<GarnetServerOptions> options)
41+
{
42+
return new SubscribeBroker<SpanByte, SpanByte, IKeySerializer<SpanByte>>(new SpanByteKeySerializer(), null,
43+
options.Value.PubSubPageSizeBytes(), options.Value.SubscriberRefreshFrequencyMs, true);
44+
}
45+
3846
/// <summary>
3947
/// Constructor
4048
/// </summary>

0 commit comments

Comments
 (0)