private Queue <String> LoadUnexistentScripts(SocketReader reader, SocketWriter writer) { var loadQueue = new Queue <String>(); // read results var result = RESPObject.Read(reader); var array = result.Cast <RESPArray>(); // if a script does not exists, send 'script load' for (int i = 0; i < array.Count; i++) { var found = array[i].Cast <RESPInteger>().Value != 0; if (!found) { var digest = _procedures.Digests[i]; _logger.Info("Script with digest {0} not found, loading...", digest); var load = GenerateLoadCommand(digest); load.WriteTo(writer); loadQueue.Enqueue(digest); } } writer.Flush(); return(loadQueue); }
private void RunInitializers(SocketReader reader, SocketWriter writer) { foreach (var initializer in Initializers) { initializer.Initialize(reader, writer); } }
private async Task ConnectionWatchDog(TcpClient tcp) { while (!_connectionCancellation.IsCancellationRequested) { try { using (tcp) using (var nstream = tcp.GetStream()) using (var writer = new SocketWriter(nstream, _options.WriteBufferSize)) using (var reader = new SocketReader(nstream, _options.ReadBufferSize)) { RunInitializers(reader, writer); var tasks = new[] { Task.Run(() => ReadAsync(reader)), Task.Run(() => WriteAsync(writer)), _options.PingTimeout != Timeout.InfiniteTimeSpan ? Task.Run(() => TimeoutWatchdogAsync()) : new Task(() => {}) }; if (_interval != Timeout.InfiniteTimeSpan) { _pingTimer.Change(_interval, _interval); // start timer } _loadFactor = 1; OnConnection(); await Task.WhenAny(tasks).ConfigureAwait(false); ThrowSocketExceptionIfExists(tasks); } } catch (SocketException soex) { // rotate endpoint _currentEndpoint = (_currentEndpoint + 1) % _endpoints.Length; _logger.Error(soex, "Connection {0} error. Switching endpoing.", _code); } catch (Exception ex) { _logger.Error(ex, "Connection {0} error.", _code); } _logger.Info("Connection {0} disconnected.", _code); _loadFactor = 100; _pending.CancelTokens(); OnDisconnection(); if (_connectionCancellation.IsCancellationRequested) { continue; } tcp = new TcpClient(); await ConnectWithTimeOut(tcp, _endpoints[_currentEndpoint]).ConfigureAwait(false); } }
public void Initialize(SocketReader reader, SocketWriter writer) { if (!ShouldLoadScripts(writer)) { return; } var loadQueue = LoadUnexistentScripts(reader, writer); ValidateScriptLoadingResults(reader, loadQueue); }
public void Initialize(SocketReader reader, SocketWriter writer) { if (_commands == null || _commands.Length == 0) { return; } SendCommands(writer); writer.Flush(); ReadResults(reader); }
internal static RESPBulkString Load(SocketReader reader) { Int32 byteLength = reader.ReadInt32(); if (byteLength < 0) { return(Null); } else { return(new RESPBulkString(reader.ReadString(byteLength))); } }
internal static RESPError Load(SocketReader reader) { var line = reader.ReadString(); var space = line.IndexOf(' '); if (space != -1) { return(new RESPError(line.Substring(0, space), line.Substring(space + 1))); } else { return(new RESPError(line)); } }
public void Initialize(SocketReader reader, SocketWriter writer) { var currentSubscriptions = _subscriptions.GetAllSubscribeCommands(); if (currentSubscriptions.Any()) { foreach (var command in currentSubscriptions) { command.WriteTo(writer); } writer.Flush(); } }
private void ReadResults(SocketReader reader) { foreach (var command in _commands) { var response = RESPObject.Read(reader); _logger.Info(" <- Response for initialization command '{0}' is type '{1}'.", command.Header, response != null ? response.Header.ToString() : "<null>."); if (response == null) { throw new RedisClientSocketException("Initialization command did not return any response."); } if (response.Header == RESPHeaders.Error) { throw new RedisClientCommandException(response.Cast <RESPError>()); } } }
private async Task ReadAsync(SocketReader reader) { try { while (!_connectionCancellation.IsCancellationRequested) { _logger.Debug("{0} listening...", _code); var resp = await RESPObject.ReadAsync(reader, _connectionCancellation.Token).ConfigureAwait(false); _logger.Debug("{0} Received response of type {1}.", _code, resp.Header); RegisterActivity(); ProcessResponse(resp); } } catch (OperationCanceledException) { } catch (ObjectDisposedException) { } catch (IOException) { } }
internal static RESPArray Load(SocketReader reader) { Int32 itemCount = reader.ReadInt32(); if (itemCount < 0) { return(RESPArray.Empty); } var array = new RESPArray(itemCount); for (int i = 0; i < itemCount; i++) { var obj = RESPObject.Read(reader); if (obj == null) { throw new RESPException("Cannot read array elements."); } array._items[i] = obj; } return(array); }
static RESPObject ProcessResponse(Char?header, SocketReader reader) { if (!header.HasValue) { return(null); } switch (header) { case RESPHeaders.SimpleString: return(RESPSimpleString.Load(reader)); case RESPHeaders.BulkString: return(RESPBulkString.Load(reader)); case RESPHeaders.Array: return(RESPArray.Load(reader)); case RESPHeaders.Error: return(RESPError.Load(reader)); case RESPHeaders.Integer: return(RESPInteger.Load(reader)); default: throw new RESPException("Unrecognized RESP header (byte): " + (byte)header.Value); } }
private void ValidateScriptLoadingResults(SocketReader reader, Queue <String> loadQueue) { // for loaded scripts, read responses and ensure // returned SHA1 fits the locally calculated one while (loadQueue.Any()) { var digest = loadQueue.Dequeue(); var result = RESPObject.Read(reader); if (result == null) { throw new RedisClientParsingException("Cannot read responses."); } try { var resultDigest = result.Cast <RESPString>().Value; if (digest != resultDigest) { throw new RedisClientParsingException("Script digest differs."); } _logger.Info("Script with digest {0} loaded.", digest); } catch (RedisClientException rcex) { _logger.Error(rcex, "Script with digest {0} failed to load.", digest); _procedures.SetFaulted(digest, rcex); } catch (Exception cmdEx) { _logger.Error(cmdEx, "Script with digest {0} failed to load.", digest); _procedures.SetFaulted(digest, new RedisClientParsingException("Error validating script digest", cmdEx)); } } }
internal static RESPObject Read(SocketReader reader) { var first = reader.ReadRESPHeader(); return(ProcessResponse(first, reader)); }
internal static TRESP Read <TRESP>(SocketReader reader) where TRESP : RESPObject { return((TRESP)Read(reader)); }
internal static async Task <RESPObject> ReadAsync(SocketReader reader, CancellationToken cancel) { var first = await reader.ReadRESPHeaderAsync(cancel).ConfigureAwait(false); return(ProcessResponse(first, reader)); }
internal static RESPInteger Load(SocketReader reader) { return(new RESPInteger(reader.ReadInt64())); }
internal static RESPSimpleString Load(SocketReader reader) { return(new RESPSimpleString(reader.ReadString())); }