private PhysicalBridge CreateBridge(ConnectionType type, TextWriter log)
        {
            multiplexer.Trace(type.ToString());
            var bridge = new PhysicalBridge(this, type);

            bridge.TryConnect(log);
            return(bridge);
        }
示例#2
0
        public void Execute()
        {
            var snapshot = pending;

            pending = null;
            if (snapshot == null || snapshot.Count == 0)
            {
                return;
            }

            // group into per-bridge chunks
            var byBridge = new Dictionary <PhysicalBridge, List <Message> >();

            // optimisation: assume most things are in a single bridge
            PhysicalBridge lastBridge = null;
            List <Message> lastList   = null;

            foreach (var message in snapshot)
            {
                var server = multiplexer.SelectServer(message);
                if (server == null)
                {
                    FailNoServer(snapshot);
                    throw ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, multiplexer.IncludePerformanceCountersInExceptions, message.Command, message, server, multiplexer.GetServerSnapshot());
                }
                var bridge = server.GetBridge(message.Command);
                if (bridge == null)
                {
                    FailNoServer(snapshot);
                    throw ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, multiplexer.IncludePerformanceCountersInExceptions, message.Command, message, server, multiplexer.GetServerSnapshot());
                }

                // identity a list
                List <Message> list;
                if (bridge == lastBridge)
                {
                    list = lastList;
                }
                else if (!byBridge.TryGetValue(bridge, out list))
                {
                    list = new List <Message>();
                    byBridge.Add(bridge, list);
                }
                lastBridge = bridge;
                lastList   = list;

                list.Add(message);
            }

            foreach (var pair in byBridge)
            {
                if (!pair.Key.TryEnqueue(pair.Value, pair.Key.ServerEndPoint.IsSlave))
                {
                    FailNoServer(pair.Value);
                }
            }
        }
 internal void RequestWrite(PhysicalBridge bridge, bool forced)
 {
     if (bridge == null) return;
     var tmp = SocketManager;
     if (tmp != null)
     {
         Trace("Requesting write: " + bridge.Name);
         tmp.RequestWrite(bridge, forced);
     }
 }
 public PhysicalBridge GetBridge(ConnectionType type, bool create = true, LogProxy log = null)
 {
     if (isDisposed)
     {
         return(null);
     }
     return(type switch
     {
         ConnectionType.Interactive => interactive ?? (create ? interactive = CreateBridge(ConnectionType.Interactive, log) : null),
         ConnectionType.Subscription => subscription ?? (create ? subscription = CreateBridge(ConnectionType.Subscription, log) : null),
         _ => null,
     });
        public void Dispose()
        {
            isDisposed = true;
            var tmp = interactive;

            interactive = null;
            tmp?.Dispose();

            tmp          = subscription;
            subscription = null;
            tmp?.Dispose();
        }
        private PhysicalBridge CreateBridge(ConnectionType type, TextWriter log)
        {
            if (Multiplexer.IsDisposed)
            {
                return(null);
            }
            Multiplexer.Trace(type.ToString());
            var bridge = new PhysicalBridge(this, type, Multiplexer.TimeoutMilliseconds);

            bridge.TryConnect(log);
            return(bridge);
        }
 public PhysicalConnection(PhysicalBridge bridge)
 {
     lastWriteTickCount = lastReadTickCount = Environment.TickCount;
     lastBeatTickCount = 0;
     this.connectionType = bridge.ConnectionType;
     this.multiplexer = bridge.Multiplexer;
     this.ChannelPrefix = multiplexer.RawConfig.ChannelPrefix;
     if (this.ChannelPrefix != null && this.ChannelPrefix.Length == 0) this.ChannelPrefix = null; // null tests are easier than null+empty
     var endpoint = bridge.ServerEndPoint.EndPoint;
     physicalName = connectionType + "#" + Interlocked.Increment(ref totalCount) + "@" + Format.ToString(endpoint);
     this.bridge = bridge;
     OnCreateEcho();
 }
示例#8
0
        internal void RequestWrite(PhysicalBridge bridge, bool forced)
        {
            if (bridge == null)
            {
                return;
            }
            var tmp = SocketManager;

            if (tmp != null)
            {
                Trace("Requesting write: " + bridge.Name);
                tmp.RequestWrite(bridge, forced);
            }
        }
        public PhysicalBridge GetBridge(ConnectionType type, bool create = true, TextWriter log = null)
        {
            if (isDisposed)
            {
                return(null);
            }
            switch (type)
            {
            case ConnectionType.Interactive:
                return(interactive ?? (create ? interactive = CreateBridge(ConnectionType.Interactive, log) : null));

            case ConnectionType.Subscription:
                return(subscription ?? (create ? subscription = CreateBridge(ConnectionType.Subscription, log) : null));
            }
            return(null);
        }
        public PhysicalConnection(PhysicalBridge bridge)
        {
            lastWriteTickCount = lastReadTickCount = Environment.TickCount;
            lastBeatTickCount = 0;
            this.connectionType = bridge.ConnectionType;
            this.multiplexer = bridge.Multiplexer;
            this.ChannelPrefix = multiplexer.RawConfig.ChannelPrefix;
            if (this.ChannelPrefix != null && this.ChannelPrefix.Length == 0) this.ChannelPrefix = null; // null tests are easier than null+empty
            var endpoint = bridge.ServerEndPoint.EndPoint;
            physicalName = connectionType + "#" + Interlocked.Increment(ref totalCount) + "@" + Format.ToString(endpoint);
            this.bridge = bridge;
            multiplexer.Trace("Connecting...", physicalName);

            this.socketToken = multiplexer.SocketManager.BeginConnect(endpoint, this);
            //socket.SendTimeout = socket.ReceiveTimeout = multiplexer.TimeoutMilliseconds;
            OnCreateEcho();
        }
        public PhysicalConnection(PhysicalBridge bridge)
        {
            lastWriteTickCount  = lastReadTickCount = Environment.TickCount;
            lastBeatTickCount   = 0;
            this.connectionType = bridge.ConnectionType;
            this.multiplexer    = bridge.Multiplexer;
            this.ChannelPrefix  = multiplexer.RawConfig.ChannelPrefix;
            if (this.ChannelPrefix != null && this.ChannelPrefix.Length == 0)
            {
                this.ChannelPrefix = null;                                                               // null tests are easier than null+empty
            }
            var endpoint = bridge.ServerEndPoint.EndPoint;

            physicalName = connectionType + "#" + Interlocked.Increment(ref totalCount) + "@" + Format.ToString(endpoint);
            this.bridge  = bridge;
            OnCreateEcho();
        }
 internal void RequestWrite(PhysicalBridge bridge, bool forced)
 {
     if (Interlocked.CompareExchange(ref bridge.inWriteQueue, 1, 0) == 0 || forced)
     {
         lock (writeQueue)
         {
             writeQueue.Enqueue(bridge);
             if (writeQueue.Count == 1)
             {
                 Monitor.PulseAll(writeQueue);
             }
             else if (writeQueue.Count >= 2)
             { // struggling are we? let's have some help dealing with the backlog
                 ThreadPool.QueueUserWorkItem(writeOneQueue, this);
             }
         }
     }
 }
示例#13
0
        public void Dispose()
        {
            isDisposed = true;
            var tmp = interactive;

            interactive = null;
            if (tmp != null)
            {
                tmp.Dispose();
            }

            tmp          = subscription;
            subscription = null;
            if (tmp != null)
            {
                tmp.Dispose();
            }
        }
        public PhysicalBridge GetBridge(RedisCommand command, bool create = true)
        {
            if (isDisposed)
            {
                return(null);
            }
            switch (command)
            {
            case RedisCommand.SUBSCRIBE:
            case RedisCommand.UNSUBSCRIBE:
            case RedisCommand.PSUBSCRIBE:
            case RedisCommand.PUNSUBSCRIBE:
                return(subscription ?? (create ? subscription = CreateBridge(ConnectionType.Subscription, null) : null));

            default:
                return(interactive ?? (create ? interactive = CreateBridge(ConnectionType.Interactive, null) : null));
            }
        }
        public PhysicalConnection(PhysicalBridge bridge)
        {
            lastWriteTickCount = lastReadTickCount = Environment.TickCount;
            lastBeatTickCount  = 0;
            connectionType     = bridge.ConnectionType;
            Multiplexer        = bridge.Multiplexer;
            ChannelPrefix      = Multiplexer.RawConfig.ChannelPrefix;
            if (ChannelPrefix?.Length == 0)
            {
                ChannelPrefix = null;                             // null tests are easier than null+empty
            }
            var endpoint = bridge.ServerEndPoint.EndPoint;

            physicalName = connectionType + "#" + Interlocked.Increment(ref totalCount) + "@" + Format.ToString(endpoint);
            Bridge       = bridge;
#if NETSTANDARD1_5
            endRead = EndReadFactory(this);
#endif
            OnCreateEcho();
        }
        public ServerEndPoint(ConnectionMultiplexer multiplexer, EndPoint endpoint, TextWriter log)
        {
            this.multiplexer = multiplexer;
            this.endpoint    = endpoint;
            var config = multiplexer.RawConfig;

            version           = config.DefaultVersion;
            slaveReadOnly     = true;
            isSlave           = false;
            databases         = 0;
            writeEverySeconds = config.KeepAlive > 0 ? config.KeepAlive : 60;
            interactive       = CreateBridge(ConnectionType.Interactive, log);
            serverType        = ServerType.Standalone;

            // overrides for twemproxy
            if (multiplexer.RawConfig.Proxy == Proxy.Twemproxy)
            {
                databases  = 1;
                serverType = ServerType.Twemproxy;
            }
        }
        public PhysicalConnection(PhysicalBridge bridge)
        {
            lastWriteTickCount  = lastReadTickCount = Environment.TickCount;
            lastBeatTickCount   = 0;
            this.connectionType = bridge.ConnectionType;
            this.multiplexer    = bridge.Multiplexer;
            this.ChannelPrefix  = multiplexer.RawConfig.ChannelPrefix;
            if (this.ChannelPrefix != null && this.ChannelPrefix.Length == 0)
            {
                this.ChannelPrefix = null;                                                               // null tests are easier than null+empty
            }
            var endpoint = bridge.ServerEndPoint.EndPoint;

            physicalName = connectionType + "#" + Interlocked.Increment(ref totalCount) + "@" + Format.ToString(endpoint);
            this.bridge  = bridge;
            multiplexer.Trace("Connecting...", physicalName);

            this.socketToken = multiplexer.SocketManager.BeginConnect(endpoint, this);
            //socket.SendTimeout = socket.ReceiveTimeout = multiplexer.TimeoutMilliseconds;
            OnCreateEcho();
        }
 public static void CompleteSyncOrAsync(this PhysicalBridge bridge, ICompletable operation)
 => CompletionManager.CompleteSyncOrAsyncImpl(bridge?.completionManager, operation);
 internal void RequestWrite(PhysicalBridge bridge, bool forced)
 {
     if (Interlocked.CompareExchange(ref bridge.inWriteQueue, 1, 0) == 0 || forced)
     {
         lock (writeQueue)
         {
             writeQueue.Enqueue(bridge);
             if (writeQueue.Count == 1)
             {
                 Monitor.PulseAll(writeQueue);
             }
             else if (writeQueue.Count >= 2)
             { // struggling are we? let's have some help dealing with the backlog
                 ThreadPool.QueueUserWorkItem(writeOneQueue, this);
             }
         }
     }
 }
 internal void QueueDirectFireAndForget <T>(Message message, ResultProcessor <T> processor, PhysicalBridge bridge = null)
 {
     if (message != null)
     {
         message.SetSource(processor, null);
         multiplexer.Trace("Enqueue: " + message);
         (bridge ?? GetBridge(message.Command)).TryEnqueue(message, isSlave);
     }
 }
        internal Task <T> QueueDirectAsync <T>(Message message, ResultProcessor <T> processor, object asyncState = null, PhysicalBridge bridge = null)
        {
            var tcs    = TaskSource.CreateDenyExecSync <T>(asyncState);
            var source = ResultBox <T> .Get(tcs);

            message.SetSource(processor, source);
            if (bridge == null)
            {
                bridge = GetBridge(message.Command);
            }
            if (!bridge.TryEnqueue(message, isSlave))
            {
                ConnectionMultiplexer.ThrowFailed(tcs, ExceptionFactory.NoConnectionAvailable(multiplexer.IncludeDetailInExceptions, message.Command, message, this));
            }
            return(tcs.Task);
        }
        internal Task <T> WriteDirectAsync <T>(Message message, ResultProcessor <T> processor, object asyncState = null, PhysicalBridge bridge = null)
        {
            var source = TaskResultBox <T> .Create(out var tcs, asyncState);

            message.SetSource(processor, source);
            if (bridge == null)
            {
                bridge = GetBridge(message.Command);
            }

            WriteResult result;

            if (bridge == null)
            {
                result = WriteResult.NoConnectionAvailable;
            }
            else
            {
                var write = bridge.TryWriteAsync(message, isSlave);
                if (!write.IsCompletedSuccessfully)
                {
                    return(WriteDirectAsync_Awaited <T>(this, message, write, tcs));
                }
                result = write.Result;
            }

            if (result != WriteResult.Success)
            {
                var ex = Multiplexer.GetException(result, message, this);
                ConnectionMultiplexer.ThrowFailed(tcs, ex);
            }
            return(tcs.Task);
        }
        internal void WriteDirectFireAndForgetSync <T>(Message message, ResultProcessor <T> processor, PhysicalBridge bridge = null)
        {
            if (message != null)
            {
                message.SetSource(processor, null);
                Multiplexer.Trace("Enqueue: " + message);
#pragma warning disable CS0618
                (bridge ?? GetBridge(message.Command)).TryWriteSync(message, isSlave);
#pragma warning restore CS0618
            }
        }
 public static void IncrementSyncCount(this PhysicalBridge bridge)
 => bridge?.completionManager?.IncrementSyncCount();
        internal Task <T> WriteDirectAsync <T>(Message message, ResultProcessor <T> processor, object asyncState = null, PhysicalBridge bridge = null)
        {
            var tcs    = TaskSource.Create <T>(asyncState);
            var source = ResultBox <T> .Get(tcs);

            message.SetSource(processor, source);
            if (bridge == null)
            {
                bridge = GetBridge(message.Command);
            }
            var result = bridge.TryWrite(message, isSlave);

            if (result != WriteResult.Success)
            {
                var ex = Multiplexer.GetException(result, message, this);
                ConnectionMultiplexer.ThrowFailed(tcs, ex);
            }
            return(tcs.Task);
        }