-
Notifications
You must be signed in to change notification settings - Fork 244
/
Copy pathProgram.cs
146 lines (126 loc) · 5.84 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets;
using Microsoft.Extensions.Configuration;
#if DATABASE
using Npgsql;
#endif
namespace PlatformBenchmarks
{
public class Program
{
public static string[] Args;
public static async Task Main(string[] args)
{
Args = args;
Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.ApplicationName));
#if !DATABASE
Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.Paths.Plaintext));
Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.Paths.Json));
#else
Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.Paths.FortunesRaw));
Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.Paths.FortunesDapper));
Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.Paths.FortunesEf));
Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.Paths.SingleQuery));
Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.Paths.Updates));
Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.Paths.MultipleQueries));
#endif
DateHeader.SyncDateTimer();
var host = BuildWebHost(args);
var config = (IConfiguration)host.Services.GetService(typeof(IConfiguration));
BatchUpdateString.DatabaseServer = config.Get<AppSettings>().Database;
#if DATABASE
try
{
await BenchmarkApplication.RawDb.PopulateCache();
}
catch (Exception ex)
{
Console.WriteLine($"Error trying to populate database cache: {ex}");
}
#endif
await host.RunAsync();
}
public static IWebHost BuildWebHost(string[] args)
{
Console.WriteLine($"BuildWebHost()");
Console.WriteLine($"Args: {string.Join(' ', args)}");
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
#if DEBUG || DEBUG_DATABASE
.AddUserSecrets<Program>()
#endif
.AddEnvironmentVariables()
.AddEnvironmentVariables(prefix: "ASPNETCORE_")
.AddCommandLine(args)
.Build();
var appSettings = config.Get<AppSettings>();
#if DATABASE
Console.WriteLine($"Database: {appSettings.Database}");
Console.WriteLine($"ConnectionString: {appSettings.ConnectionString}");
if (appSettings.Database == DatabaseServer.PostgreSql)
{
BenchmarkApplication.RawDb = new RawDb(new ConcurrentRandom(), appSettings);
BenchmarkApplication.DapperDb = new DapperDb(appSettings);
BenchmarkApplication.EfDb = new EfDb(appSettings);
}
else
{
throw new NotSupportedException($"Database '{appSettings.Database}' is not supported, check your app settings.");
}
#endif
var hostBuilder = new WebHostBuilder()
.UseBenchmarksConfiguration(config)
.UseKestrel((context, options) =>
{
var endPoints = context.Configuration.CreateIPEndPoints();
foreach (var endPoint in endPoints)
{
options.Listen(endPoint, builder =>
{
builder.UseHttpApplication<BenchmarkApplication>();
});
}
})
.UseStartup<Startup>();
hostBuilder.UseSockets(options =>
{
options.WaitForDataBeforeAllocatingBuffer = false;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
options.UnsafePreferInlineScheduling = Environment.GetEnvironmentVariable("DOTNET_SYSTEM_NET_SOCKETS_INLINE_COMPLETIONS") == "1";
// Allow multiple processes bind to the same port. This also "works" on Windows in that it will
// prevent address in use errors and hand off to another process if no others are available,
// but it wouldn't round-robin new connections between processes like it will on Linux.
options.CreateBoundListenSocket = endpoint =>
{
if (endpoint is not IPEndPoint ip)
{
return SocketTransportOptions.CreateDefaultBoundListenSocket(endpoint);
}
// Normally, we'd call CreateDefaultBoundListenSocket for the IPEndpoint too, but we need
// to set ReuseAddress before calling bind, and CreateDefaultBoundListenSocket calls bind.
var listenSocket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
// Kestrel expects IPv6Any to bind to both IPv6 and IPv4
if (ip.Address.Equals(IPAddress.IPv6Any))
{
listenSocket.DualMode = true;
}
listenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
listenSocket.Bind(ip);
return listenSocket;
};
}
});
var host = hostBuilder.Build();
return host;
}
}
}