예제 #1
0
        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);
        }
예제 #2
0
 private void RunInitializers(SocketReader reader, SocketWriter writer)
 {
     foreach (var initializer in Initializers)
     {
         initializer.Initialize(reader, writer);
     }
 }
예제 #3
0
 private void SendCommands(SocketWriter writer)
 {
     foreach (var command in _commands)
     {
         _logger.Info(" -> Sending initialization command '{0}'.", command.Header);
         command.WriteTo(writer);
     }
 }
예제 #4
0
        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);
            }
        }
예제 #5
0
        internal void WriteTo(SocketWriter writter)
        {
            writter.Write(RESPHeaders.Array);
            writter.WriteLine(_parts.Count.ToString());

            foreach (var item in _parts)
            {
                item.WriteTo(writter);
            }
        }
예제 #6
0
        public void Initialize(SocketReader reader, SocketWriter writer)
        {
            if (!ShouldLoadScripts(writer))
            {
                return;
            }

            var loadQueue = LoadUnexistentScripts(reader, writer);

            ValidateScriptLoadingResults(reader, loadQueue);
        }
예제 #7
0
        public void Initialize(SocketReader reader, SocketWriter writer)
        {
            if (_commands == null || _commands.Length == 0)
            {
                return;
            }

            SendCommands(writer);

            writer.Flush();

            ReadResults(reader);
        }
예제 #8
0
 internal override void WriteTo(SocketWriter writer)
 {
     if (Value == null)
     {
         writer.Write(_empty);
     }
     else
     {
         writer.Write(RESPHeaders.BulkString);
         writer.WriteLine(_scount);
         writer.WriteLine(Value);
     }
 }
예제 #9
0
        public void Initialize(SocketReader reader, SocketWriter writer)
        {
            var currentSubscriptions = _subscriptions.GetAllSubscribeCommands();

            if (currentSubscriptions.Any())
            {
                foreach (var command in currentSubscriptions)
                {
                    command.WriteTo(writer);
                }

                writer.Flush();
            }
        }
예제 #10
0
        private Boolean ShouldLoadScripts(SocketWriter writer)
        {
            if (_procedures.Digests.Any())
            {
                var array = new RESPCommand(new RESPCommandLiteral("SCRIPT"), false);
                array.Add(new RESPCommandLiteral("exists"));
                foreach (var digest in _procedures.Digests)
                {
                    _logger.Info("Checking existence of script digest {0}...", digest);
                    array.Add(new RESPCommandLiteral(digest));
                }

                array.WriteTo(writer);
                writer.Flush();
                return(true);
            }
            return(false);
        }
예제 #11
0
        private async Task WriteAsync(SocketWriter writer)
        {
            try
            {
                while (!_connectionCancellation.IsCancellationRequested)
                {
                    var token = _requests.Take(_connectionCancellation.Token);

                    if (token == null || token.IsCancelled)
                    {
                        return;
                    }

                    WriteToken(writer, token);
                }
            }
            catch (OperationCanceledException) { }
            catch (InvalidOperationException) { }
            catch (ArgumentNullException) { }
        }
예제 #12
0
        private void WriteToken(SocketWriter writer, ExecutionToken token)
        {
            try
            {
                _logger.Debug("{0} Received token {1}.", _code, token);

                var hasCommands = false;

                foreach (var command in ExecuteOperation(token))
                {
                    // some subscription commands are aggregated
                    // and produce no commands.
                    if (!hasCommands)
                    {
                        hasCommands = true;
                        _pending.Enqueue(token);
                    }
                    command.WriteTo(writer);
                }

                if (hasCommands)
                {
                    writer.Flush(); // using the async version kills performance, worth investigating why
                    _logger.Debug("{0} flushed buffer.", _code);
                }
            }
            catch (OperationCanceledException)
            {
                token.SetCancelled();
                throw;
            }
            catch (Exception ex)
            {
                token.SetFaulted(ex);
                throw;
            }
        }
예제 #13
0
 internal abstract void WriteTo(SocketWriter writer);
예제 #14
0
 internal override void WriteTo(SocketWriter writer)
 {
     writer.Write(_resp);
 }
예제 #15
0
 // TODO: SOLID.LSP broken?
 // this is just a marker to be replaced
 internal override void WriteTo(SocketWriter writer)
 {
     throw new NotImplementedException("Parameters are replaced during parameter binding, and this method should be never called.");
 }