public RedisConnectionPoolMember(RedisSocket socket, int dbIndex, RedisConnectionSettings settings) { DbIndex = dbIndex; Socket = socket; m_Settings = settings; PooledTime = DateTime.UtcNow; }
protected override IRedisConnection NewConnection(RedisSocket socket, int dbIndex, RedisRole expectedRole, bool connectImmediately = true) { var settings = (Settings as RedisPoolSettings) ?? RedisPoolSettings.Default; return(new RedisDbConnection(Name, expectedRole, settings, null, OnReleaseSocket, dbIndex, socket.IsConnected() ? socket : null, connectImmediately)); }
protected virtual void OnConnect(RedisSocket socket) { if (socket.IsConnected()) { var settings = (Settings ?? RedisPoolSettings.Default); if (!settings.Password.IsEmpty() && Auth(socket, settings.Password)) { socket.SetAuthenticated(true); } if (!settings.ClientName.IsEmpty()) { SetClientName(socket, settings.ClientName); } if (!NeedsToDiscoverRole()) { socket.Role = ExpectedRole; } else { var role = DiscoverRole(socket); ValidateRole(role); } } }
protected virtual RedisRawResponse ReadResponse(RedisSocket socket) { if (socket == null) { throw new ArgumentNullException("socket"); } ValidateNotDisposed(); if (socket.IsConnected()) { Error = null; try { var result = ProcessResponse(socket); OnResponse(result); return(result); } catch (Exception e) { Error = e; } } return(RedisVoidResponse.Void); }
protected virtual void DoConfigure(RedisSocket socket) { SetIOLoopbackFastPath(socket); var linger = new LingerOption(false, 0); socket.LingerState = linger; var sendTimeout = GetSendTimeout(); var receiveTimeout = GetReceiveTimeout(); if (sendTimeout > 0) { socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, sendTimeout == int.MaxValue ? Timeout.Infinite : sendTimeout); } if (receiveTimeout > 0) { socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, receiveTimeout == int.MaxValue ? Timeout.Infinite : receiveTimeout); } socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, linger); socket.NoDelay = true; }
protected override RedisRole DiscoverRole(RedisSocket socket) { var role = base.DiscoverRole(socket); ValidateRole(RedisRole.Sentinel); return(role); }
public RedisContinuousReaderCtx(RedisContinuousReader reader, RedisConnection connection, RedisSocket socket, Action <IRedisRawResponse> onReceive) : base(connection.Settings) { Reader = reader; Connection = connection; Socket = socket; m_OnReceive = onReceive; }
protected bool TryToReceive(RedisSocket socket, int length, out int receivedLength) { receivedLength = 0; if (m_WritePosition == Beginning || m_ReadPosition > m_WritePosition - 1) { receivedLength = BeginReceive(socket, length); return(receivedLength > 0); } return(true); }
protected override IRedisConnection OnNewConnection(RedisSocket socket, int dbIndex, RedisRole role, bool connectImmediately = true) { var settings = Settings as RedisSentinelSettings ?? RedisSentinelSettings.Default; return(new RedisSentinelConnection(Name, settings, null, OnReleaseSocket, socket, true)); }
protected override IRedisConnection OnNewConnection(RedisSocket socket, int dbIndex, RedisRole role, bool connectImmediately = true) { var settings = (Settings as RedisPoolSettings) ?? RedisPoolSettings.Default; return(new RedisContinuousReaderConnection(Name, RedisRole.Master, settings, OnReceiveResponse, null, OnReleaseSocket, socket, true)); }
public RedisSocketWriter(RedisSocket socket, bool useAsyncIfNeeded = true, bool ownsStream = false) { if (socket == null) { throw new ArgumentNullException("socket"); } m_Socket = socket; m_OwnsSocket = ownsStream; m_UseAsyncIfNeeded = useAsyncIfNeeded; }
protected bool Auth(RedisSocket socket, string password) { if (!password.IsEmpty()) { ValidateNotDisposed(); using (var cmd = new RedisCommand(-1, RedisCommandList.Auth, RedisCommandType.SendAndReceive, password.ToBytes())) { return(cmd.ExpectOK(new RedisSocketContext(socket, Settings), true)); } } return(true); }
protected virtual void OnReleaseSocket(IRedisConnection connection, RedisSocket socket) { ValidateNotDisposed(); try { CompleteSocketRelease(connection, socket); } finally { Release(); } }
protected bool SetClientName(RedisSocket socket, string clientName) { if (clientName == null) { throw new ArgumentNullException("clientName"); } ValidateNotDisposed(); using (var cmd = new RedisCommand(-1, RedisCommandList.Client, RedisCommandType.SendAndReceive, RedisCommandList.SetName, clientName.ToBytes())) { return(cmd.ExpectOK(new RedisSocketContext(socket, Settings), true)); } }
protected int ReadByte(RedisSocket socket) { int receivedLength; if (TryToReceive(socket, 1, out receivedLength)) { var b = m_Buffer[m_ReadPosition]; IncrementReadPosition(); return(b); } return(receivedLength); }
internal void ReuseSocket(RedisSocket socket) { var provider = m_ConnectionProvider; if (provider.IsAlive()) { provider.ReuseSocket(socket); } else if (socket.IsAlive()) { socket.DisposeSocket(); } }
protected virtual RedisSocket NewSocket(IPAddress ipAddress) { var socket = new RedisSocket(ipAddress != null ? ipAddress.AddressFamily : AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp, Settings.UseSsl); var onCreateSocket = m_CreateAction; if (onCreateSocket != null) { onCreateSocket(this, socket); } return(socket); }
protected void SetIOLoopbackFastPath(RedisSocket socket) { if (RedisCommon.IsWindows) { var optionInValue = BitConverter.GetBytes(1); try { socket.IOControl(SIO_LOOPBACK_FAST_PATH, optionInValue, null); } catch (Exception) { } } }
private void SelectDB(RedisSocket socket, int dbIndex) { if (socket != null) { dbIndex = Math.Min(Math.Max(dbIndex, RedisConstants.UninitializedDbIndex), RedisConstants.MaxDbIndex); if (dbIndex > RedisConstants.UninitializedDbIndex && socket.DbIndex != dbIndex && socket.SelectDB(Settings, dbIndex)) { m_DbIndex = socket.DbIndex; } } }
public void BeginReceive(Action <RedisContinuousReader> onComplete, Action <IRedisRawResponse> onReceive) { ValidateNotDisposed(); if (Interlocked.CompareExchange(ref m_ReceiveState, RedisConstants.One, RedisConstants.Zero) == RedisConstants.Zero) { m_Connection.ConnectAsync(). ContinueWith((asyncTask) => { RedisSocket socket = null; if (asyncTask.IsCompleted) { socket = asyncTask.Result; } Interlocked.Exchange(ref m_Socket, socket); try { if (socket != null) { try { using (var ctx = new RedisContinuousReaderCtx(this, m_Connection, socket, onReceive)) { Interlocked.Exchange(ref m_Context, ctx); ctx.Read(); } } finally { Interlocked.Exchange(ref m_Context, null); } } } finally { Interlocked.Exchange(ref m_ReceiveState, RedisConstants.Zero); Interlocked.Exchange(ref m_Socket, null); socket.DisposeSocket(); } }).ContinueWith(t => { if (onComplete != null) { onComplete(this); } }); } }
protected bool EatCRLF(RedisSocket socket) { var data = ReadBytes(socket, RedisConstants.CRLFLength); if ((data == null || data.Length != RedisConstants.CRLFLength || data[0] != '\r' || data[1] != '\n')) { if (!Receiving) { return(false); } throw new RedisException("Corrupted redis response, not a line end", RedisErrorCode.CorruptResponse); } return(true); }
protected override IRedisConnection NewConnection(RedisSocket socket, int dbIndex, RedisRole expectedRole, bool connectImmediately = true) { var connection = m_Connection; if (!connection.IsAlive()) { lock (m_ConnectionLock) { connection = m_Connection; if (!connection.IsAlive()) { m_Connection = (connection = OnNewConnection(socket, dbIndex, expectedRole, connectImmediately)); } } } return(connection); }
internal RedisDbConnection(string name, RedisRole expectedRole, RedisConnectionSettings settings, Action <RedisConnection, RedisSocket> onCreateSocket, Action <RedisConnection, RedisSocket> onReleaseSocket, int dbIndex, RedisSocket socket = null, bool connectImmediately = false) : base(name, expectedRole, settings, onCreateSocket, onReleaseSocket, socket, false) { m_DbIndex = Math.Min(Math.Max(dbIndex, RedisConstants.UninitializedDbIndex), RedisConstants.MaxDbIndex); try { if (connectImmediately) { ConnectInternal(); } } catch (Exception) { } SelectDB(m_DbIndex); }
public Task WriteToAsync(RedisSocket socket, bool flush = true) { if (socket == null) { throw new ArgumentNullException("socket"); } Action <Stream> action = (stream) => { using (var writer = new RedisStreamWriter(stream, flush)) { WriteTo(writer); } }; return(action.InvokeAsync(socket.GetBufferedStream())); }
protected override void CompleteSocketRelease(IRedisConnection connection, RedisSocket socket) { if (socket != null) { lock (m_SocketLock) { RedisSocket currentSocket; if (Disposed) { currentSocket = Interlocked.CompareExchange(ref m_Socket, null, socket); if (currentSocket != null) { currentSocket.DisposeSocket(); } else if (socket != null) { socket.DisposeSocket(); } return; } currentSocket = m_Socket; if (!currentSocket.IsAlive()) { Interlocked.Exchange(ref m_Socket, null); currentSocket = null; } if (ReferenceEquals(currentSocket, socket)) { return; } if (socket.IsAlive()) { currentSocket = Interlocked.Exchange(ref m_Socket, socket); if (currentSocket != null) { currentSocket.DisposeSocket(); } } } } }
public void WriteTo(RedisSocket socket, bool flush = true) { if (socket == null) { throw new ArgumentNullException("socket"); } var stream = socket.GetBufferedStream(); if (!stream.CanWrite) { throw new ArgumentException("Can not write to closed stream", "stream"); } using (var writer = new RedisStreamWriter(stream, flush)) { WriteTo(writer); } }
protected void EnqueueSocket(RedisSocket socket) { if (socket.IsAlive()) { var member = new RedisConnectionPoolMember(socket, socket.DbIndex, Settings); lock (m_MemberStoreLock) { var prevTail = Interlocked.Exchange(ref m_MemberStoreTail, member); if (prevTail != null) { var store = m_MemberStore; if (store != null) { store.AddLast(prevTail); } } } } }
internal RedisConnection(string name, RedisRole expectedRole, RedisConnectionSettings settings, Action <RedisConnection, RedisSocket> onCreateSocket, Action <RedisConnection, RedisSocket> onReleaseSocket, RedisSocket socket = null, bool connectImmediately = false) { if (settings == null) { throw new RedisFatalException(new ArgumentNullException("settings")); } if (onReleaseSocket == null) { throw new RedisFatalException(new ArgumentNullException("onReleaseSocket")); } RedisConnectionStats.IncrInUseConnections(); m_ExpectedRole = expectedRole; m_Settings = settings ?? RedisConnectionSettings.Default; m_CreateAction = onCreateSocket; m_ReleaseAction = onReleaseSocket; m_Name = !name.IsEmpty() ? name : (GetType().Name + ", " + m_Id.ToString()); if ((socket != null) && socket.Connected) { m_Socket = socket; m_State = (int)RedisConnectionState.Connected; } try { if (connectImmediately) { ConnectInternal(); } } catch (Exception) { } }
public static Task <int> ReceiveAsync(this RedisSocket socket, byte[] data, int offset, int count) { var tcs = new TaskCompletionSource <int>(socket); socket.GetRealStream().BeginRead(data, offset, count, ar => { var innerTcs = ar.DiscoverTaskCompletionSource <int>(); try { innerTcs.TrySetResult(((RedisSocket)innerTcs.Task.AsyncState).EndReceive(ar)); } catch (OperationCanceledException) { innerTcs.TrySetCanceled(); } catch (Exception e) { innerTcs.TrySetException(e); } }, tcs); return(tcs.Task); }
public static Task DisconnectAsync(this RedisSocket socket, bool reuseSocket = false) { var tcs = new TaskCompletionSource <object>(socket); socket.BeginDisconnect(reuseSocket, ar => { var innerTcs = ar.DiscoverTaskCompletionSource <object>(); try { ((RedisSocket)innerTcs.Task.AsyncState).EndDisconnect(ar); innerTcs.TrySetResult(null); } catch (OperationCanceledException) { innerTcs.TrySetCanceled(); } catch (Exception e) { innerTcs.TrySetException(e); } }, tcs); return(tcs.Task); }