예제 #1
0
        protected override Task Send(int streamIndex, IList <Message> messages)
        {
            var keys      = new string[] { _key };
            var arguments = new object[] { RedisMessage.ToBytes(messages) };

            return(_connection.Scripting.Eval(
                       _db,
                       @"local newId = redis.call('INCR', KEYS[1])
                  local payload = newId .. ' ' .. ARGV[1]
                  return redis.call('PUBLISH', KEYS[1], payload)",
                       keys,
                       arguments));
        }
예제 #2
0
        protected override Task Send(int streamIndex, IList <Message> messages)
        {
            var context = new SendContext(_key, messages, _connection);

            // Increment the channel number
            return(_connection.Strings.Increment(_db, _key)
                   .Then((id, ctx) =>
            {
                byte[] data = RedisMessage.ToBytes(id, ctx.Messages);

                return ctx.Connection.Publish(ctx.Key, data);
            },
                         context));
        }
예제 #3
0
 private void OnMessage(int streamIndex, RedisMessage message)
 {
     // locked to avoid overlapping calls (even though we have set the mode
     // to preserve order on the subscription)
     lock (_callbackLock)
     {
         if (lastId.HasValue && message.Id < lastId.Value)
         {
             _trace.TraceEvent(TraceEventType.Error, 0, $"ID regression occurred. The next message ID {message.Id} was less than the previous message {lastId.Value}");
         }
         lastId = message.Id;
         OnReceived(streamIndex, message.Id, message.ScaleoutMessage);
     }
 }
예제 #4
0
        public static RedisMessage FromBytes(byte[] data)
        {
            using (var stream = new MemoryStream(data))
            {
                var binaryReader = new BinaryReader(stream);
                var message      = new RedisMessage();

                message.Id = (ulong)binaryReader.ReadInt64();
                int    count  = binaryReader.ReadInt32();
                byte[] buffer = binaryReader.ReadBytes(count);

                message.ScaleoutMessage = ScaleoutMessage.FromBytes(buffer);
                return(message);
            }
        }
예제 #5
0
        public static RedisMessage FromBytes(byte[] data)
        {
            using (var stream = new MemoryStream(data))
            {
                var binaryReader = new BinaryReader(stream);
                var message = new RedisMessage();

                message.Id = (ulong)binaryReader.ReadInt64();
                int count = binaryReader.ReadInt32();
                byte[] buffer = binaryReader.ReadBytes(count);

                message.ScaleoutMessage = ScaleoutMessage.FromBytes(buffer);
                return message;
            }
        }
예제 #6
0
        public static RedisMessage FromBytes(IMessageEncryptor encryptor, byte[] data, TraceSource trace)
        {
            using (var stream = new MemoryStream(data))
            {
                var message = new RedisMessage();

                // read message id from memory stream until SPACE character
                var messageIdBuilder = new StringBuilder(20);
                do
                {
                    // it is safe to read digits as bytes because they encoded by single byte in UTF-8
                    int charCode = stream.ReadByte();
                    if (charCode == -1)
                    {
                        trace.TraceVerbose("Received Message could not be parsed.");
                        throw new EndOfStreamException(Resources.Error_EndOfStreamRedis);
                    }

                    char c = (char)charCode;

                    if (c == ' ')
                    {
                        message.Id       = ulong.Parse(messageIdBuilder.ToString(), CultureInfo.InvariantCulture);
                        messageIdBuilder = null;
                    }
                    else
                    {
                        messageIdBuilder.Append(c);
                    }
                }while (messageIdBuilder != null);


                var encryptedBinaryReader = new BinaryReader(stream);
                var encryptedData         = encryptedBinaryReader.ReadBytes((int)(stream.Length - stream.Position));
                var decryptedData         = encryptor.Decrypt(encryptedData);

                using (var dataStream = new MemoryStream(decryptedData))
                    using (var decryptedReader = new BinaryReader(dataStream))
                    {
                        int    count  = decryptedReader.ReadInt32();
                        byte[] buffer = decryptedReader.ReadBytes(count);

                        message.ScaleoutMessage = ScaleoutMessage.FromBytes(buffer);
                    }

                return(message);
            }
        }
예제 #7
0
        public static RedisMessage FromBytes(byte[] data)
        {
            using (var stream = new MemoryStream(data))
            {
                var binaryReader = new BinaryReader(stream);
                var message = new RedisMessage();
                message.Id = binaryReader.ReadInt64();
                message.Messages = new List<Message>();
                int count = binaryReader.ReadInt32();
                for (int i = 0; i < count; i++)
                {
                    message.Messages.Add(Message.ReadFrom(stream));
                }

                return message;
            }
        }
예제 #8
0
        public static RedisMessage FromBytes(byte[] data)
        {
            using (var stream = new MemoryStream(data))
            {
                var binaryReader = new BinaryReader(stream);
                var message      = new RedisMessage();
                message.Id       = binaryReader.ReadInt64();
                message.Messages = new List <Message>();
                int count = binaryReader.ReadInt32();
                for (int i = 0; i < count; i++)
                {
                    message.Messages.Add(Message.ReadFrom(stream));
                }

                return(message);
            }
        }
예제 #9
0
        private Task <bool> ExecuteTransaction(RedisTransaction transaction, long?oldId, IList <Message> messages)
        {
            _trace.TraceVerbose("ExecuteTransaction({0})", oldId);

            // New target id
            long newId = (oldId ?? 0) + 1;

            // TODO: Don't do this everytime
            byte[] data = RedisMessage.ToBytes(newId, messages);

            // These don't need to be observed
            transaction.AddCondition(Condition.KeyEquals(_db, _key, oldId));
            transaction.Strings.Increment(_db, _key);
            transaction.Publish(_key, data);

            // Execute the transaction
            return(transaction.Execute());
        }
예제 #10
0
        public static RedisMessage FromBytes(byte[] data, TraceSource trace)
        {
            using (var stream = new MemoryStream(data))
            {
                var message = new RedisMessage();

                // read message id from memory stream until SPACE character
                var messageIdBuilder = new StringBuilder(20);
                do
                {
                    // it is safe to read digits as bytes because they encoded by single byte in UTF-8
                    int charCode = stream.ReadByte();
                    if (charCode == -1)
                    {
                        trace.TraceVerbose("Received Message could not be parsed.");
                        throw new EndOfStreamException(Resources.Error_EndOfStreamRedis);
                    }

                    char c = (char)charCode;

                    if (c == ' ')
                    {
                        message.Id = ulong.Parse(messageIdBuilder.ToString(), CultureInfo.InvariantCulture);
                        messageIdBuilder = null;
                    }
                    else
                    {
                        messageIdBuilder.Append(c);
                    }
                }
                while (messageIdBuilder != null);

                var binaryReader = new BinaryReader(stream);
                int count = binaryReader.ReadInt32();
                byte[] buffer = binaryReader.ReadBytes(count);

                message.ScaleoutMessage = ScaleoutMessage.FromBytes(buffer);
                return message;
            }
        }
예제 #11
0
        public static RedisMessage FromBytes(byte[] data, ILogger logger)
        {
            using (var stream = new MemoryStream(data))
            {
                var message = new RedisMessage();

                // read message id from memory stream until SPACE character
                var messageIdBuilder = new StringBuilder(20);
                do
                {
                    // it is safe to read digits as bytes because they encoded by single byte in UTF-8
                    int charCode = stream.ReadByte();
                    if (charCode == -1)
                    {
                        logger.LogVerbose("Received Message could not be parsed.");
                        throw new EndOfStreamException();
                    }
                    char c = (char)charCode;
                    if (c == ' ')
                    {
                        message.Id       = ulong.Parse(messageIdBuilder.ToString(), CultureInfo.InvariantCulture);
                        messageIdBuilder = null;
                    }
                    else
                    {
                        messageIdBuilder.Append(c);
                    }
                }while (messageIdBuilder != null);

                var    binaryReader = new BinaryReader(stream);
                int    count        = binaryReader.ReadInt32();
                byte[] buffer       = binaryReader.ReadBytes(count);

                message.ScaleoutMessage = ScaleoutMessage.FromBytes(buffer);
                return(message);
            }
        }
예제 #12
0
 private void OnMessage(int streamIndex, RedisMessage message)
 {
     // locked to avoid overlapping calls (even though we have set the mode 
     // to preserve order on the subscription)
     lock (_callbackLock)
     {
         OnReceived(streamIndex, message.Id, message.ScaleoutMessage);
     }
 }