From 79488f4b79790de322b237894c0e62a5b6fc01ac Mon Sep 17 00:00:00 2001 From: Akhilesh Agarwal Date: Mon, 1 Jul 2024 23:22:07 -0400 Subject: [PATCH] Added support for .NET Framework 4.8 --- .../IMemcachedClientConfiguration.cs | 16 ++- .../MemcachedClientConfiguration.cs | 38 +++++-- .../Configuration/MemcachedClientOptions.cs | 12 +- src/Enyim.Caching/Enyim.Caching.csproj | 65 ++++++----- ...imMemcachedApplicationBuilderExtensions.cs | 4 +- ...yimMemcachedServiceCollectionExtensions.cs | 14 ++- .../Memcached/DefaultServerPool.cs | 66 +++++++---- src/Enyim.Caching/Memcached/MemcachedNode.cs | 103 +++++++++++++----- src/Enyim.Caching/Memcached/PooledSocket.cs | 57 ++++++++-- .../Memcached/Protocol/Binary/BinaryNode.cs | 19 +++- .../Memcached/Protocol/Binary/BinaryPool.cs | 23 ++-- 11 files changed, 294 insertions(+), 123 deletions(-) diff --git a/src/Enyim.Caching/Configuration/IMemcachedClientConfiguration.cs b/src/Enyim.Caching/Configuration/IMemcachedClientConfiguration.cs index 8d50c1c3..922f9a8d 100755 --- a/src/Enyim.Caching/Configuration/IMemcachedClientConfiguration.cs +++ b/src/Enyim.Caching/Configuration/IMemcachedClientConfiguration.cs @@ -49,26 +49,30 @@ public interface IMemcachedClientConfiguration bool SuppressException { get; } +#if NET5_0_OR_GREATER SslClientAuthenticationOptions SslClientAuth { get; } +#endif } } #region [ License information ] + /* ************************************************************ - * + * * Copyright (c) 2010 Attila Kisk? enyim.com - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * ************************************************************/ -#endregion + +#endregion \ No newline at end of file diff --git a/src/Enyim.Caching/Configuration/MemcachedClientConfiguration.cs b/src/Enyim.Caching/Configuration/MemcachedClientConfiguration.cs index ea2b5254..ea657399 100755 --- a/src/Enyim.Caching/Configuration/MemcachedClientConfiguration.cs +++ b/src/Enyim.Caching/Configuration/MemcachedClientConfiguration.cs @@ -43,6 +43,7 @@ public MemcachedClientConfiguration( _logger = loggerFactory.CreateLogger(); var options = optionsAccessor.Value; +#if NET5_0_OR_GREATER if ((options == null || options.Servers.Count == 0) && configuration != null) { var section = configuration.GetSection("enyimMemcached"); @@ -56,6 +57,7 @@ public MemcachedClientConfiguration( options.AddDefaultServer(); } } +#endif ConfigureServers(options); @@ -84,7 +86,8 @@ public MemcachedClientConfiguration( _logger.LogInformation($"{nameof(SocketPool.QueueTimeout)}: {SocketPool.QueueTimeout}"); SocketPool.ConnectionIdleTimeout = options.SocketPool.ConnectionIdleTimeout; - _logger.LogInformation($"{nameof(SocketPool.ConnectionIdleTimeout)}: {SocketPool.ConnectionIdleTimeout}"); + _logger.LogInformation( + $"{nameof(SocketPool.ConnectionIdleTimeout)}: {SocketPool.ConnectionIdleTimeout}"); SocketPool.InitPoolTimeout = options.SocketPool.InitPoolTimeout; @@ -117,14 +120,17 @@ public MemcachedClientConfiguration( } catch (Exception ex) { - _logger.LogError(new EventId(), ex, $"Unable to load authentication type {options.Authentication.Type}."); + _logger.LogError(new EventId(), ex, + $"Unable to load authentication type {options.Authentication.Type}."); } } UseSslStream = options.UseSslStream; UseIPv6 = options.UseIPv6; SuppressException = options.SuppressException; +#if NET5_0_OR_GREATER SslClientAuth = options.SslClientAuth; +#endif if (!string.IsNullOrEmpty(options.KeyTransformer)) { @@ -213,7 +219,10 @@ private void ConfigureServers(MemcachedClientOptions options) if (!IPAddress.TryParse(server.Address, out var address)) { address = Dns.GetHostAddresses(server.Address) - .FirstOrDefault(i => i.AddressFamily == (options.UseIPv6 ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork)); + .FirstOrDefault(i => + i.AddressFamily == (options.UseIPv6 + ? AddressFamily.InterNetworkV6 + : AddressFamily.InterNetwork)); if (address == null) { @@ -339,8 +348,8 @@ IMemcachedNodeLocator IMemcachedClientConfiguration.CreateNodeLocator() if (f != null) return f.Create(); return NodeLocator == null - ? new SingleNodeLocator() - : (IMemcachedNodeLocator)FastActivator.Create(NodeLocator); + ? new SingleNodeLocator() + : (IMemcachedNodeLocator)FastActivator.Create(NodeLocator); } ITranscoder IMemcachedClientConfiguration.CreateTranscoder() @@ -352,7 +361,8 @@ IServerPool IMemcachedClientConfiguration.CreatePool() { switch (Protocol) { - case MemcachedProtocol.Text: return new DefaultServerPool(this, new Memcached.Protocol.Text.TextOperationFactory(), _logger); + case MemcachedProtocol.Text: + return new DefaultServerPool(this, new Memcached.Protocol.Text.TextOperationFactory(), _logger); case MemcachedProtocol.Binary: return new BinaryPool(this, _logger); } @@ -362,28 +372,32 @@ IServerPool IMemcachedClientConfiguration.CreatePool() public bool UseSslStream { get; private set; } public bool UseIPv6 { get; private set; } public bool SuppressException { get; private set; } +#if NET5_0_OR_GREATER public SslClientAuthenticationOptions SslClientAuth { get; private set; } +#endif #endregion } } #region [ License information ] + /* ************************************************************ - * + * * Copyright (c) 2010 Attila Kisk? enyim.com - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * ************************************************************/ -#endregion + +#endregion \ No newline at end of file diff --git a/src/Enyim.Caching/Configuration/MemcachedClientOptions.cs b/src/Enyim.Caching/Configuration/MemcachedClientOptions.cs index df47d4a6..e87de735 100644 --- a/src/Enyim.Caching/Configuration/MemcachedClientOptions.cs +++ b/src/Enyim.Caching/Configuration/MemcachedClientOptions.cs @@ -28,7 +28,9 @@ public class MemcachedClientOptions : IOptions public bool SuppressException { get; set; } = true; +#if NET5_0_OR_GREATER public SslClientAuthenticationOptions SslClientAuth { get; set; } +#endif public IProviderFactory NodeLocatorFactory { get; set; } @@ -49,8 +51,8 @@ public void AddPlainTextAuthenticator(string zone, string userName, string passw Parameters = new Dictionary { { $"{nameof(zone)}", zone }, - { $"{nameof(userName)}", userName}, - { $"{nameof(password)}", password} + { $"{nameof(userName)}", userName }, + { $"{nameof(password)}", password } } }; } @@ -79,7 +81,9 @@ public class SocketPoolOptions public TimeSpan QueueTimeout { get; set; } = new TimeSpan(0, 0, 0, 0, 100); public TimeSpan ConnectionIdleTimeout { get; set; } = TimeSpan.Zero; public TimeSpan InitPoolTimeout { get; set; } = new TimeSpan(0, 1, 0); - public INodeFailurePolicyFactory FailurePolicyFactory { get; set; } = new ThrottlingFailurePolicyFactory(5, TimeSpan.FromMilliseconds(2000)); + + public INodeFailurePolicyFactory FailurePolicyFactory { get; set; } = + new ThrottlingFailurePolicyFactory(5, TimeSpan.FromMilliseconds(2000)); public void CheckPoolSize() { @@ -110,4 +114,4 @@ private void CheckTimeout(string paramName, TimeSpan value) } } } -} +} \ No newline at end of file diff --git a/src/Enyim.Caching/Enyim.Caching.csproj b/src/Enyim.Caching/Enyim.Caching.csproj index 10b4dae4..24b02191 100755 --- a/src/Enyim.Caching/Enyim.Caching.csproj +++ b/src/Enyim.Caching/Enyim.Caching.csproj @@ -1,33 +1,44 @@  - - EnyimMemcachedCore is a Memcached client library for .NET. Add services.AddEnyimMemcached() in Startup. Inject IMemcachedClient into constructors. - cnblogs.com - net6.0;net7.0;net8.0 - true - EnyimMemcachedCore - EnyimMemcachedCore - README.md - memcached;cache - https://github.com/cnblogs/EnyimMemcachedCore - git - https://github.com/cnblogs/EnyimMemcachedCore - Apache-2.0 - False - latest - $(NoWarn);SYSLIB0011 - + + EnyimMemcachedCore is a Memcached client library for .NET. Add services.AddEnyimMemcached() in Startup. Inject IMemcachedClient into constructors. + cnblogs.com + net6.0;net7.0;net8.0;net48;net481 + true + EnyimMemcachedCore + EnyimMemcachedCore + README.md + memcached;cache + https://github.com/cnblogs/EnyimMemcachedCore + git + https://github.com/cnblogs/EnyimMemcachedCore + Apache-2.0 + False + latest + $(NoWarn);SYSLIB0011 + - - - - + + + - - - + + + + + + + - - - + + + + + + + + + + + diff --git a/src/Enyim.Caching/EnyimMemcachedApplicationBuilderExtensions.cs b/src/Enyim.Caching/EnyimMemcachedApplicationBuilderExtensions.cs index 219b1148..432f2a3c 100644 --- a/src/Enyim.Caching/EnyimMemcachedApplicationBuilderExtensions.cs +++ b/src/Enyim.Caching/EnyimMemcachedApplicationBuilderExtensions.cs @@ -12,6 +12,7 @@ namespace Microsoft.AspNetCore.Builder { public static class EnyimMemcachedApplicationBuilderExtensions { +#if NET5_0_OR_GREATER public static IApplicationBuilder UseEnyimMemcached(this IApplicationBuilder app) { var logger = app.ApplicationServices.GetService>(); @@ -27,5 +28,6 @@ public static IApplicationBuilder UseEnyimMemcached(this IApplicationBuilder app return app; } +#endif } -} +} \ No newline at end of file diff --git a/src/Enyim.Caching/EnyimMemcachedServiceCollectionExtensions.cs b/src/Enyim.Caching/EnyimMemcachedServiceCollectionExtensions.cs index 16f67ba2..a7477a92 100644 --- a/src/Enyim.Caching/EnyimMemcachedServiceCollectionExtensions.cs +++ b/src/Enyim.Caching/EnyimMemcachedServiceCollectionExtensions.cs @@ -14,6 +14,7 @@ namespace Microsoft.Extensions.DependencyInjection { public static class EnyimMemcachedServiceCollectionExtensions { +#if NET5_0_OR_GREATER public static IServiceCollection AddEnyimMemcached( this IServiceCollection services, string sectionKey = "enyimMemcached", @@ -32,6 +33,7 @@ public static IServiceCollection AddEnyimMemcached( return services.AddEnyimMemcachedInternal( s => s.AddOptions().BindConfiguration(sectionKey), asDistributedCache); } +#endif public static IServiceCollection AddEnyimMemcached( this IServiceCollection services, @@ -52,6 +54,7 @@ public static IServiceCollection AddEnyimMemcached( s => s.Configure(setupAction), asDistributedCache); } +#if NET5_0_OR_GREATER public static IServiceCollection AddEnyimMemcached( this IServiceCollection services, IConfigurationSection configurationSection, @@ -92,6 +95,7 @@ public static IServiceCollection AddEnyimMemcached( return services.AddEnyimMemcachedInternal( s => s.Configure(section), asDistributedCache); } +#endif private static IServiceCollection AddEnyimMemcachedInternal( this IServiceCollection services, @@ -115,6 +119,7 @@ private static IServiceCollection AddEnyimMemcachedInternal( return services; } +#if NET5_0_OR_GREATER public static IServiceCollection AddEnyimMemcached( this IServiceCollection services, string sectionKey) @@ -149,12 +154,13 @@ public static IServiceCollection AddEnyimMemcached( } return services.AddEnyimMemcached( - s => s.Configure(configuration.GetSection(sectionKey))); + s => s.Configure(configuration.GetSection(sectionKey))); } +#endif public static IServiceCollection AddEnyimMemcached( - this IServiceCollection services, - Action configure) + this IServiceCollection services, + Action configure) { services.AddOptions(); configure?.Invoke(services); @@ -173,4 +179,4 @@ public static IServiceCollection AddEnyimMemcached( return services; } } -} +} \ No newline at end of file diff --git a/src/Enyim.Caching/Memcached/DefaultServerPool.cs b/src/Enyim.Caching/Memcached/DefaultServerPool.cs index 3dc7affd..9c73e078 100644 --- a/src/Enyim.Caching/Memcached/DefaultServerPool.cs +++ b/src/Enyim.Caching/Memcached/DefaultServerPool.cs @@ -44,13 +44,23 @@ public DefaultServerPool( ~DefaultServerPool() { - try { ((IDisposable)this).Dispose(); } - catch { } + try + { + ((IDisposable)this).Dispose(); + } + catch + { + } } protected virtual IMemcachedNode CreateNode(EndPoint endpoint) { +#if NET5_0_OR_GREATER return new MemcachedNode(endpoint, _configuration.SocketPool, _logger, _configuration.UseSslStream, _configuration.UseIPv6, _configuration.SslClientAuth); +#else + return new MemcachedNode(endpoint, _configuration.SocketPool, _logger, _configuration.UseSslStream, + _configuration.UseIPv6); +#endif } private void rezCallback(object state) @@ -152,7 +162,8 @@ private void NodeFail(IMemcachedNode node) { if (_isDisposed) { - if (_logger.IsEnabled(LogLevel.Warning)) _logger.LogWarning("Got a node fail but the pool is already disposed. Ignoring."); + if (_logger.IsEnabled(LogLevel.Warning)) + _logger.LogWarning("Got a node fail but the pool is already disposed. Ignoring."); return; } @@ -206,15 +217,13 @@ IEnumerable IServerPool.GetWorkingNodes() void IServerPool.Start() { - _allNodes = _configuration.Servers. - Select(ep => - { - var node = CreateNode(ep); - node.Failed += NodeFail; + _allNodes = _configuration.Servers.Select(ep => + { + var node = CreateNode(ep); + node.Failed += NodeFail; - return node; - }). - ToArray(); + return node; + }).ToArray(); // initialize the locator var locator = _configuration.CreateNodeLocator(); @@ -230,6 +239,7 @@ event Action IServerPool.NodeFailed } #endregion + #region [ IDisposable ] void IDisposable.Dispose() @@ -246,14 +256,26 @@ void IDisposable.Dispose() // the nodes one last time var nd = _nodeLocator as IDisposable; if (nd != null) - try { nd.Dispose(); } - catch (Exception e) { _logger.LogError(nameof(DefaultServerPool), e); } + try + { + nd.Dispose(); + } + catch (Exception e) + { + _logger.LogError(nameof(DefaultServerPool), e); + } _nodeLocator = null; for (var i = 0; i < _allNodes.Length; i++) - try { _allNodes[i].Dispose(); } - catch (Exception e) { _logger.LogError(nameof(DefaultServerPool), e); } + try + { + _allNodes[i].Dispose(); + } + catch (Exception e) + { + _logger.LogError(nameof(DefaultServerPool), e); + } // stop the timer if (_resurrectTimer != null) @@ -270,21 +292,23 @@ void IDisposable.Dispose() } #region [ License information ] + /* ************************************************************ - * + * * Copyright (c) 2010 Attila Kisk? enyim.com - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * ************************************************************/ -#endregion + +#endregion \ No newline at end of file diff --git a/src/Enyim.Caching/Memcached/MemcachedNode.cs b/src/Enyim.Caching/Memcached/MemcachedNode.cs index 0732371c..23a30bfc 100755 --- a/src/Enyim.Caching/Memcached/MemcachedNode.cs +++ b/src/Enyim.Caching/Memcached/MemcachedNode.cs @@ -3,9 +3,7 @@ using Enyim.Caching.Memcached.Results; using Enyim.Caching.Memcached.Results.Extensions; using Enyim.Collections; - using Microsoft.Extensions.Logging; - using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -38,19 +36,27 @@ public class MemcachedNode : IMemcachedNode private readonly TimeSpan _initPoolTimeout; private bool _useSslStream; private bool _useIPv6; +#if NET5_0_OR_GREATER private readonly SslClientAuthenticationOptions _sslClientAuthOptions; +#endif public MemcachedNode( EndPoint endpoint, ISocketPoolConfiguration socketPoolConfig, ILogger logger, bool useSslStream, +#if NET5_0_OR_GREATER bool useIPv6, SslClientAuthenticationOptions sslClientAuthOptions) +#else + bool useIPv6) +#endif { _endPoint = endpoint; _useSslStream = useSslStream; +#if NET5_0_OR_GREATER _sslClientAuthOptions = sslClientAuthOptions; +#endif EndPointString = endpoint?.ToString().Replace("Unspecified/", string.Empty); _config = socketPoolConfig; @@ -136,14 +142,22 @@ public bool Ping() Interlocked.Exchange(ref _internalPoolImpl, newPool); - try { oldPool.Dispose(); } - catch { } + try + { + oldPool.Dispose(); + } + catch + { + } } return true; } //could not reconnect - catch { return false; } + catch + { + return false; + } } /// @@ -170,7 +184,8 @@ public IPooledSocketResult Acquire() if (_logger.IsEnabled(LogLevel.Information)) { - _logger.LogInformation("MemcachedInitPool-cost: {0}ms", (DateTime.Now - startTime).TotalMilliseconds); + _logger.LogInformation("MemcachedInitPool-cost: {0}ms", + (DateTime.Now - startTime).TotalMilliseconds); } } } @@ -218,7 +233,8 @@ public async Task AcquireAsync() if (_logger.IsEnabled(LogLevel.Information)) { - _logger.LogInformation("MemcachedInitPool-cost: {0}ms", (DateTime.Now - startTime).TotalMilliseconds); + _logger.LogInformation("MemcachedInitPool-cost: {0}ms", + (DateTime.Now - startTime).TotalMilliseconds); } } } @@ -243,8 +259,13 @@ public async Task AcquireAsync() ~MemcachedNode() { - try { ((IDisposable)this).Dispose(); } - catch { } + try + { + ((IDisposable)this).Dispose(); + } + catch + { + } } /// @@ -361,7 +382,6 @@ internal void InitPool() if (_logger.IsEnabled(LogLevel.Debug)) _logger.LogDebug("Pool has been inited for {0} with {1} sockets", _endPoint, _minItems); - } catch (Exception e) { @@ -396,7 +416,6 @@ internal async Task InitPoolAsync() if (_logger.IsEnabled(LogLevel.Debug)) _logger.LogDebug("Pool has been inited for {0} with {1} sockets", _endPoint, _minItems); - } catch (Exception e) { @@ -520,7 +539,8 @@ public IPooledSocketResult Acquire() if (_logger.IsEnabled(LogLevel.Information)) { - _logger.LogInformation("MemcachedAcquire-CreateSocket: {0}ms", (DateTime.Now - startTime).TotalMilliseconds); + _logger.LogInformation("MemcachedAcquire-CreateSocket: {0}ms", + (DateTime.Now - startTime).TotalMilliseconds); } result.Value = socket; @@ -650,7 +670,8 @@ public async Task AcquireAsync() if (_logger.IsEnabled(LogLevel.Information)) { - _logger.LogInformation("MemcachedAcquire-CreateSocket: {0}ms", (DateTime.Now - startTime).TotalMilliseconds); + _logger.LogInformation("MemcachedAcquire-CreateSocket: {0}ms", + (DateTime.Now - startTime).TotalMilliseconds); } result.Value = socket; @@ -780,7 +801,8 @@ private bool TryPopPooledSocket(out PooledSocket pooledSocket) { if (_logger.IsEnabled(LogLevel.Information)) { - _logger.LogInformation("Connection idle timeout {idleTimeout} reached.", _connectionIdleTimeout); + _logger.LogInformation("Connection idle timeout {idleTimeout} reached.", + _connectionIdleTimeout); } socket.Destroy(); @@ -804,8 +826,13 @@ private bool TryPopPooledSocket(out PooledSocket pooledSocket) ~InternalPoolImpl() { - try { ((IDisposable)this).Dispose(); } - catch { } + try + { + ((IDisposable)this).Dispose(); + } + catch + { + } } /// @@ -824,8 +851,14 @@ public void Dispose() while (_freeItems.TryPop(out var socket)) { - try { socket.Destroy(); } - catch (Exception ex) { _logger.LogError(ex, $"failed to destroy {nameof(PooledSocket)}"); } + try + { + socket.Destroy(); + } + catch (Exception ex) + { + _logger.LogError(ex, $"failed to destroy {nameof(PooledSocket)}"); + } } _ownerNode = null; @@ -842,7 +875,9 @@ void IDisposable.Dispose() } #endregion + #region [ Comparer ] + internal sealed class Comparer : IEqualityComparer { public static readonly Comparer Instance = new Comparer(); @@ -857,13 +892,19 @@ int IEqualityComparer.GetHashCode(IMemcachedNode obj) return obj.EndPoint.GetHashCode(); } } + #endregion protected internal virtual PooledSocket CreateSocket() { try { - var ps = new PooledSocket(_endPoint, _config.ConnectionTimeout, _config.ReceiveTimeout, _logger, _useSslStream, _useIPv6, _sslClientAuthOptions); + var ps = new PooledSocket(_endPoint, _config.ConnectionTimeout, _config.ReceiveTimeout, _logger, +#if NET5_0_OR_GREATER + _useSslStream, _useIPv6, _sslClientAuthOptions); +#else + _useSslStream, _useIPv6); +#endif ps.Connect(); return ps; } @@ -872,14 +913,18 @@ protected internal virtual PooledSocket CreateSocket() _logger.LogError(ex, $"Create {nameof(PooledSocket)}"); throw; } - } protected internal virtual async Task CreateSocketAsync() { try { - var ps = new PooledSocket(_endPoint, _config.ConnectionTimeout, _config.ReceiveTimeout, _logger, _useSslStream, _useIPv6, _sslClientAuthOptions); + var ps = new PooledSocket(_endPoint, _config.ConnectionTimeout, _config.ReceiveTimeout, _logger, +#if NET5_0_OR_GREATER + _useSslStream, _useIPv6, _sslClientAuthOptions); +#else + _useSslStream, _useIPv6); +#endif await ps.ConnectAsync(); return ps; } @@ -923,6 +968,7 @@ protected virtual IPooledSocketResult ExecuteOperation(IOperation op) { readResult.Combine(result); } + return result; } catch (IOException e) @@ -939,11 +985,12 @@ protected virtual IPooledSocketResult ExecuteOperation(IOperation op) } else { - var errorMsg = string.IsNullOrEmpty(result.Message) ? "Failed to acquire a socket from pool" : result.Message; + var errorMsg = string.IsNullOrEmpty(result.Message) + ? "Failed to acquire a socket from pool" + : result.Message; _logger.LogError(errorMsg); return result; } - } protected virtual async Task ExecuteOperationAsync(IOperation op) @@ -974,6 +1021,7 @@ protected virtual async Task ExecuteOperationAsync(IOperati result.Fail("Timeout to pooledSocket.WriteAsync"); return result; } + await writeSocketTask; //if Get, call BinaryResponse @@ -1003,6 +1051,7 @@ protected virtual async Task ExecuteOperationAsync(IOperati readResult.Combine(result); } + return result; } catch (IOException e) @@ -1026,7 +1075,9 @@ protected virtual async Task ExecuteOperationAsync(IOperati } else { - var errorMsg = string.IsNullOrEmpty(result.Message) ? "Failed to acquire a socket from pool" : result.Message; + var errorMsg = string.IsNullOrEmpty(result.Message) + ? "Failed to acquire a socket from pool" + : result.Message; _logger.LogError(errorMsg); return result; } @@ -1114,6 +1165,7 @@ event Action IMemcachedNode.Failed } #region [ License information ] + /* ************************************************************ * * Copyright (c) 2010 Attila Kisk? enyim.com @@ -1131,4 +1183,5 @@ event Action IMemcachedNode.Failed * limitations under the License. * * ************************************************************/ -#endregion + +#endregion \ No newline at end of file diff --git a/src/Enyim.Caching/Memcached/PooledSocket.cs b/src/Enyim.Caching/Memcached/PooledSocket.cs index fddc89e1..2f3d9d26 100755 --- a/src/Enyim.Caching/Memcached/PooledSocket.cs +++ b/src/Enyim.Caching/Memcached/PooledSocket.cs @@ -26,15 +26,24 @@ public partial class PooledSocket : IDisposable private NetworkStream _inputStream; private SslStream _sslStream; +#if NET5_0_OR_GREATER private readonly SslClientAuthenticationOptions _sslClientAuthOptions; - - public PooledSocket(EndPoint endpoint, TimeSpan connectionTimeout, TimeSpan receiveTimeout, ILogger logger, bool useSslStream, bool useIPv6, SslClientAuthenticationOptions sslClientAuthOptions) +#endif + +#if NET5_0_OR_GREATER + public PooledSocket(EndPoint endpoint, TimeSpan connectionTimeout, TimeSpan receiveTimeout, ILogger logger, + bool useSslStream, bool useIPv6, SslClientAuthenticationOptions sslClientAuthOptions) +#else + public PooledSocket(EndPoint endpoint, TimeSpan connectionTimeout, TimeSpan receiveTimeout, ILogger logger, + bool useSslStream, bool useIPv6) +#endif { _endpoint = endpoint; _logger = logger; _isAlive = true; _useSslStream = useSslStream; _useIPv6 = useIPv6; +#if NET5_0_OR_GREATER _sslClientAuthOptions = sslClientAuthOptions; if (_useSslStream && _sslClientAuthOptions == null) @@ -45,8 +54,9 @@ public PooledSocket(EndPoint endpoint, TimeSpan connectionTimeout, TimeSpan rece TargetHost = ((DnsEndPoint)_endpoint).Host, }; } - - var socket = new Socket(useIPv6 ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); +#endif + var socket = new Socket(useIPv6 ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork, + SocketType.Stream, ProtocolType.Tcp); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); socket.NoDelay = true; @@ -71,6 +81,7 @@ public void Connect() //Learn from https://github.com/dotnet/corefx/blob/release/2.2/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs#L180 var cts = new CancellationTokenSource(); cts.CancelAfter(_connectionTimeout); + void Cancel() { if (_socket != null && !_socket.Connected) @@ -79,6 +90,7 @@ void Cancel() _socket = null; } } + cts.Token.Register(Cancel); try @@ -106,6 +118,7 @@ void Cancel() if (success) { +#if NET5_0_OR_GREATER if (_useSslStream) { _sslStream = new SslStream(new NetworkStream(_socket)); @@ -115,6 +128,9 @@ void Cancel() { _inputStream = new NetworkStream(_socket); } +#else + _inputStream = new NetworkStream(_socket); +#endif } else { @@ -141,6 +157,7 @@ public async Task ConnectAsync() _socket.Dispose(); _socket = null; } + throw new TimeoutException($"Timeout to connect to {_endpoint}."); } } @@ -165,6 +182,7 @@ public async Task ConnectAsync() if (success) { +#if NET5_0_OR_GREATER if (_useSslStream) { _sslStream = new SslStream(new NetworkStream(_socket)); @@ -174,6 +192,9 @@ public async Task ConnectAsync() { _inputStream = new NetworkStream(_socket); } +#else + _inputStream = new NetworkStream(_socket); +#endif } else { @@ -282,7 +303,13 @@ protected void Dispose(bool disposing) { if (_socket != null) { - try { _socket.Dispose(); } catch { } + try + { + _socket.Dispose(); + } + catch + { + } } if (_inputStream != null) @@ -362,6 +389,7 @@ public int ReadByteAsync() { _isAlive = false; } + throw; } } @@ -377,7 +405,9 @@ public async Task ReadAsync(byte[] buffer, int offset, int count) { try { - int currentRead = (_useSslStream ? await _sslStream.ReadAsync(buffer, offset, shouldRead) : await _inputStream.ReadAsync(buffer, offset, shouldRead)); + int currentRead = (_useSslStream + ? await _sslStream.ReadAsync(buffer, offset, shouldRead) + : await _inputStream.ReadAsync(buffer, offset, shouldRead)); if (currentRead == count) break; if (currentRead < 1) @@ -417,7 +447,9 @@ public void Read(byte[] buffer, int offset, int count) { try { - int currentRead = (_useSslStream ? _sslStream.Read(buffer, offset, shouldRead) : _inputStream.Read(buffer, offset, shouldRead)); + int currentRead = (_useSslStream + ? _sslStream.Read(buffer, offset, shouldRead) + : _inputStream.Read(buffer, offset, shouldRead)); if (currentRead == count) break; if (currentRead < 1) @@ -433,6 +465,7 @@ public void Read(byte[] buffer, int offset, int count) { _isAlive = false; } + throw; } } @@ -455,6 +488,7 @@ public void Write(byte[] data, int offset, int length) { _isAlive = false; } + throw; } } @@ -487,6 +521,7 @@ public void Write(IList> buffers) { _sslStream.Write(buf.Array); } + _sslStream.Flush(); } else @@ -505,6 +540,7 @@ public void Write(IList> buffers) { _isAlive = false; } + _logger.LogError(ex, nameof(PooledSocket.Write)); throw; } @@ -522,6 +558,7 @@ public async Task WriteAsync(IList> buffers) { await _sslStream.WriteAsync(buf.Array, 0, buf.Count); } + await _sslStream.FlushAsync(); } else @@ -530,7 +567,8 @@ public async Task WriteAsync(IList> buffers) if (bytesTransferred <= 0) { _isAlive = false; - _logger.LogError($"Failed to {nameof(PooledSocket.WriteAsync)}. bytesTransferred: {bytesTransferred}"); + _logger.LogError( + $"Failed to {nameof(PooledSocket.WriteAsync)}. bytesTransferred: {bytesTransferred}"); ThrowHelper.ThrowSocketWriteError(_endpoint); } } @@ -541,6 +579,7 @@ public async Task WriteAsync(IList> buffers) { _isAlive = false; } + _logger.LogError(ex, nameof(PooledSocket.WriteAsync)); throw; } @@ -589,4 +628,4 @@ private IPEndPoint GetIPEndPoint(EndPoint endpoint) * * ************************************************************/ -#endregion +#endregion \ No newline at end of file diff --git a/src/Enyim.Caching/Memcached/Protocol/Binary/BinaryNode.cs b/src/Enyim.Caching/Memcached/Protocol/Binary/BinaryNode.cs index 1755d23d..18d19deb 100644 --- a/src/Enyim.Caching/Memcached/Protocol/Binary/BinaryNode.cs +++ b/src/Enyim.Caching/Memcached/Protocol/Binary/BinaryNode.cs @@ -26,9 +26,14 @@ public BinaryNode( ISaslAuthenticationProvider authenticationProvider, ILogger logger, bool useSslStream, +#if NET5_0_OR_GREATER bool useIPv6, SslClientAuthenticationOptions sslClientAuthOptions) : base(endpoint, config, logger, useSslStream, useIPv6, sslClientAuthOptions) +#else + bool useIPv6) + : base(endpoint, config, logger, useSslStream, useIPv6) +#endif { _authenticationProvider = authenticationProvider; _logger = logger; @@ -125,21 +130,23 @@ private async Task AuthAsync(PooledSocket socket) } #region [ License information ] + /* ************************************************************ - * + * * Copyright (c) 2010 Attila Kisk? enyim.com - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * ************************************************************/ -#endregion + +#endregion \ No newline at end of file diff --git a/src/Enyim.Caching/Memcached/Protocol/Binary/BinaryPool.cs b/src/Enyim.Caching/Memcached/Protocol/Binary/BinaryPool.cs index 55fff2ee..b4b49251 100644 --- a/src/Enyim.Caching/Memcached/Protocol/Binary/BinaryPool.cs +++ b/src/Enyim.Caching/Memcached/Protocol/Binary/BinaryPool.cs @@ -29,7 +29,11 @@ public BinaryPool(IMemcachedClientConfiguration configuration, ILogger logger) protected override IMemcachedNode CreateNode(EndPoint endpoint) { +#if NET5_0_OR_GREATER return new BinaryNode(endpoint, _configuration.SocketPool, _authenticationProvider, _logger, _configuration.UseSslStream, _configuration.UseIPv6, _configuration.SslClientAuth); +#else + return new BinaryNode(endpoint, _configuration.SocketPool, _authenticationProvider, _logger, _configuration.UseSslStream, _configuration.UseIPv6); +#endif } private static ISaslAuthenticationProvider GetProvider(IMemcachedClientConfiguration configuration) @@ -40,7 +44,9 @@ private static ISaslAuthenticationProvider GetProvider(IMemcachedClientConfigura if (auth != null) { Type t = auth.Type; - var provider = (t == null) ? null : Enyim.Reflection.FastActivator.Create(t) as ISaslAuthenticationProvider; + var provider = (t == null) + ? null + : Enyim.Reflection.FastActivator.Create(t) as ISaslAuthenticationProvider; if (provider != null) { @@ -51,26 +57,27 @@ private static ISaslAuthenticationProvider GetProvider(IMemcachedClientConfigura return null; } - } } #region [ License information ] + /* ************************************************************ - * + * * Copyright (c) 2010 Attila Kisk? enyim.com - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * ************************************************************/ -#endregion + +#endregion \ No newline at end of file