Commit 253c719e authored by Marc Gravell's avatar Marc Gravell

simplify build; **just** netstandard2.0; no #if fun

parent c4a5d673
......@@ -21,7 +21,7 @@
<DefaultLanguage>en-US</DefaultLanguage>
<IncludeSymbols>false</IncludeSymbols>
<LibraryTargetFrameworks>net46;netstandard2.0</LibraryTargetFrameworks>
<LibraryTargetFrameworks>netstandard2.0</LibraryTargetFrameworks>
<CoreFxVersion>4.5.0</CoreFxVersion>
<xUnitVersion>2.4.0-beta.2.build3981</xUnitVersion>
</PropertyGroup>
......
......@@ -10,27 +10,13 @@
<OutputTypeEx>Library</OutputTypeEx>
<SignAssembly>true</SignAssembly>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<LangVersion>7.2</LangVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' OR '$(TargetFramework)' == 'net46' ">
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net45' or '$(TargetFramework)' == 'net46'">
<DefineConstants>$(DefineConstants);FEATURE_PERFCOUNTER;</DefineConstants>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<!-- theses intentionally does not track CoreFxVersion -->
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
<PackageReference Include="System.Reflection.Emit.ILGeneration" Version="4.3.0" />
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.3.0" />
<PackageReference Include="System.Memory" Version="$(CoreFxVersion)" />
<PackageReference Include="System.Buffers" Version="$(CoreFxVersion)" />
<PackageReference Include="System.IO.Pipelines" Version="$(CoreFxVersion)" />
<PackageReference Include="Pipelines.Sockets.Unofficial" Version="0.2.1-alpha.33" />
<PackageReference Include="Pipelines.Sockets.Unofficial" Version="0.2.1-alpha.43" />
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="$(CoreFxVersion)" />
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -2046,12 +2046,12 @@ void add(string lk, string sk, string v)
add("ThreadPool-IO-Completion", "IOCP", iocp);
add("ThreadPool-Workers", "WORKER", worker);
data.Add(Tuple.Create("Busy-Workers", busyWorkerCount.ToString()));
#if FEATURE_PERFCOUNTER
if (IncludePerformanceCountersInExceptions)
{
add("Local-CPU", "Local-CPU", GetSystemCpuPercent());
}
#endif
sb.Append(" (Please take a look at this article for some common client-side issues that can cause timeouts: ");
sb.Append(timeoutHelpLink);
sb.Append(")");
......@@ -2085,7 +2085,6 @@ void add(string lk, string sk, string v)
}
}
#if FEATURE_PERFCOUNTER
internal static string GetThreadPoolAndCPUSummary(bool includePerformanceCounters)
{
GetThreadPoolStats(out string iocp, out string worker);
......@@ -2099,7 +2098,6 @@ private static string GetSystemCpuPercent()
? Math.Round(systemCPU, 2) + "%"
: "unavailable";
}
#endif
private static int GetThreadPoolStats(out string iocp, out string worker)
{
ThreadPool.GetMaxThreads(out int maxWorkerThreads, out int maxIoThreads);
......
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
......@@ -260,12 +261,11 @@ public static bool EmulateStaleConnection
}
#endif
#if FEATURE_PERFCOUNTER
internal static class PerfCounterHelper
{
private static readonly object staticLock = new object();
private static volatile PerformanceCounter _cpu;
private static volatile bool _disabled;
private static volatile bool _disabled = !RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
public static bool TryGetSystemCPU(out float value)
{
......@@ -306,7 +306,6 @@ public static bool TryGetSystemCPU(out float value)
return false;
}
}
#endif
#if VERBOSE
......
......@@ -124,12 +124,10 @@ internal static Exception NoConnectionAvailable(bool includeDetail, bool include
exceptionmessage.Append("; ").Append(innermostExceptionstring);
}
#if FEATURE_PERFCOUNTER
if (includeDetail)
{
exceptionmessage.Append("; ").Append(ConnectionMultiplexer.GetThreadPoolAndCPUSummary(includePerformanceCounters));
}
#endif
var ex = new RedisConnectionException(ConnectionFailureType.UnableToResolvePhysicalConnection, exceptionmessage.ToString(), innerException, message?.Status ?? CommandStatus.Unknown);
......
......@@ -15,6 +15,7 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Pipelines.Sockets.Unofficial;
namespace StackExchange.Redis
{
......@@ -834,43 +835,47 @@ private static LocalCertificateSelectionCallback GetAmbientCertificateCallback()
return null;
}
async ValueTask<SocketMode> ISocketCallback.ConnectedAsync(IDuplexPipe pipe, TextWriter log)
async ValueTask<SocketMode> ISocketCallback.ConnectedAsync(Socket socket, TextWriter log)
{
try
{
var socketMode = SocketManager.DefaultSocketMode;
var socketMode = SocketMode.Async;
// disallow connection in some cases
OnDebugAbort();
// the order is important here:
// [network]<==[ssl]<==[logging]<==[buffered]
// [Socket]<==[NetworkStream]<==[SslStream]<==[
var config = Multiplexer.RawConfig;
IDuplexPipe pipe;
if (config.Ssl)
{
throw new NotImplementedException("TLS");
//Multiplexer.LogLocked(log, "Configuring SSL");
//var host = config.SslHost;
//if (string.IsNullOrWhiteSpace(host)) host = Format.ToStringHostOnly(Bridge.ServerEndPoint.EndPoint);
//var ssl = new SslStream(stream, false, config.CertificateValidationCallback,
// config.CertificateSelectionCallback ?? GetAmbientCertificateCallback(),
// EncryptionPolicy.RequireEncryption);
//try
//{
// ssl.AuthenticateAsClient(host, config.SslProtocols);
Multiplexer.LogLocked(log, "Configuring SSL");
var host = config.SslHost;
if (string.IsNullOrWhiteSpace(host)) host = Format.ToStringHostOnly(Bridge.ServerEndPoint.EndPoint);
// Multiplexer.LogLocked(log, $"SSL connection established successfully using protocol: {ssl.SslProtocol}");
//}
//catch (AuthenticationException authexception)
//{
// RecordConnectionFailed(ConnectionFailureType.AuthenticationFailure, authexception);
// Multiplexer.Trace("Encryption failure");
// return SocketMode.Abort;
//}
//stream = ssl;
//socketMode = SocketMode.Async;
var ssl = new SslStream(new NetworkStream(socket), false, config.CertificateValidationCallback,
config.CertificateSelectionCallback ?? GetAmbientCertificateCallback(),
EncryptionPolicy.RequireEncryption);
try
{
ssl.AuthenticateAsClient(host, config.SslProtocols);
Multiplexer.LogLocked(log, $"SSL connection established successfully using protocol: {ssl.SslProtocol}");
}
catch (AuthenticationException authexception)
{
RecordConnectionFailed(ConnectionFailureType.AuthenticationFailure, authexception);
Multiplexer.Trace("Encryption failure");
return SocketMode.Abort;
}
pipe = StreamConnector.GetDuplex(ssl, name: Bridge.Name);
}
else
{
pipe = SocketConnection.Create(socket, name: Bridge.Name);
}
OnWrapForLogging(ref pipe, physicalName);
......
//using System;
//namespace StackExchange.Redis
//{
// internal static class PlatformHelper
// {
// public static bool IsMono { get; } = Type.GetType("Mono.Runtime") != null;
// public static bool IsUnix { get; } = (int)Environment.OSVersion.Platform == 4
// || (int)Environment.OSVersion.Platform == 6
// || (int)Environment.OSVersion.Platform == 128;
// public static SocketMode DefaultSocketMode = IsMono && IsUnix ? SocketMode.Async : SocketMode.Poll;
// }
//}
......@@ -182,9 +182,7 @@ public virtual bool SetResult(PhysicalConnection connection, Message message, Ra
unableToConnectError = true;
err = $"Endpoint {endpoint} serving hashslot {hashSlot} is not reachable at this point of time. Please check connectTimeout value. If it is low, try increasing it to give the ConnectionMultiplexer a chance to recover from the network disconnect. ";
}
#if FEATURE_PERFCOUNTER
err += ConnectionMultiplexer.GetThreadPoolAndCPUSummary(bridge.Multiplexer.IncludePerformanceCountersInExceptions);
#endif
}
}
}
......
#if !FEATURE_SOCKET_MODE_POLL
namespace StackExchange.Redis
{
public partial class SocketManager
{
internal const SocketMode DefaultSocketMode = SocketMode.Async;
private void OnAddRead(System.Net.Sockets.Socket socket, ISocketCallback callback)
{
throw new System.NotSupportedException();
}
}
}
#endif
\ No newline at end of file
......@@ -26,9 +26,9 @@ internal partial interface ISocketCallback
/// <summary>
/// Indicates that a socket has connected
/// </summary>
/// <param name="pipe">The network stream for this socket.</param>
/// <param name="socket">The socket.</param>
/// <param name="log">A text logger to write to.</param>
ValueTask<SocketMode> ConnectedAsync(IDuplexPipe pipe, TextWriter log);
ValueTask<SocketMode> ConnectedAsync(Socket socket, TextWriter log);
/// <summary>
/// Indicates that the socket has signalled an error condition
......@@ -173,17 +173,57 @@ public void Dispose()
}
internal SocketToken BeginConnect(EndPoint endpoint, ISocketCallback callback, ConnectionMultiplexer multiplexer, TextWriter log)
{
void RunWithCompletionType(Func<AsyncCallback, IAsyncResult> beginAsync, AsyncCallback asyncCallback)
{
void proxyCallback(IAsyncResult ar)
{
if (!ar.CompletedSynchronously)
{
asyncCallback(ar);
}
}
var result = beginAsync(proxyCallback);
if (result.CompletedSynchronously)
{
result.AsyncWaitHandle.WaitOne();
asyncCallback(result);
}
}
var addressFamily = endpoint.AddressFamily == AddressFamily.Unspecified ? AddressFamily.InterNetwork : endpoint.AddressFamily;
var socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp);
SocketConnection.SetRecommendedClientOptions(socket);
if (addressFamily == AddressFamily.Unix) socket.NoDelay = false;
try
{
var formattedEndpoint = Format.ToString(endpoint);
var t = SocketConnection.ConnectAsync(endpoint, _pipeOptions,
onConnected: conn => EndConnectAsync(conn, multiplexer, log, callback),
socket: socket);
GC.KeepAlive(t); // make compiler happier
var tuple = Tuple.Create(socket, callback);
multiplexer.LogLocked(log, "BeginConnect: {0}", formattedEndpoint);
// A work-around for a Mono bug in BeginConnect(EndPoint endpoint, AsyncCallback callback, object state)
if (endpoint is DnsEndPoint dnsEndpoint)
{
RunWithCompletionType(
cb => socket.BeginConnect(dnsEndpoint.Host, dnsEndpoint.Port, cb, tuple),
ar => {
multiplexer.LogLocked(log, "EndConnect: {0}", formattedEndpoint);
EndConnectImpl(ar, multiplexer, log, tuple);
multiplexer.LogLocked(log, "Connect complete: {0}", formattedEndpoint);
});
}
else
{
RunWithCompletionType(
cb => socket.BeginConnect(endpoint, cb, tuple),
ar => {
multiplexer.LogLocked(log, "EndConnect: {0}", formattedEndpoint);
EndConnectImpl(ar, multiplexer, log, tuple);
multiplexer.LogLocked(log, "Connect complete: {0}", formattedEndpoint);
});
}
}
catch (NotImplementedException ex)
{
......@@ -223,16 +263,18 @@ internal void Shutdown(SocketToken token)
Shutdown(token.Socket);
}
private async Task EndConnectAsync(SocketConnection connection, ConnectionMultiplexer multiplexer, TextWriter log, ISocketCallback callback)
private async void EndConnectImpl(IAsyncResult ar, ConnectionMultiplexer multiplexer, TextWriter log, Tuple<Socket, ISocketCallback> tuple)
{
var socket = tuple.Item1;
var callback = tuple.Item2;
try
{
bool ignoreConnect = false;
var socket = connection?.Socket;
ShouldIgnoreConnect(callback, ref ignoreConnect);
ShouldIgnoreConnect(tuple.Item2, ref ignoreConnect);
if (ignoreConnect) return;
socket.EndConnect(ar);
var socketMode = callback == null ? SocketMode.Abort : await callback.ConnectedAsync(connection, log);
var socketMode = callback == null ? SocketMode.Abort : await callback.ConnectedAsync(socket, log);
switch (socketMode)
{
case SocketMode.Async:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment