Example #1
1
        private void Broadcast(string eventKey, Message message)
        {
            LockedList<Action<IList<Message>>> callbacks;
            if (_waitingTasks.TryGetValue(eventKey, out callbacks))
            {
                var delegates = callbacks.CopyWithLock();
                var messages = new[] { message };

                _trace.Source.TraceInformation("MessageBus: Sending message {0} to {1} waiting connections", message.Id, delegates.Count);

                foreach (var callback in delegates)
                {
                    if (callback != null)
                    {
                        callback.Invoke(messages);
                    }
                }
            }
        }
        /// <summary>
        /// Invoked when a payload is received from the backplane. There should only be one active call at any time.
        /// </summary>
        /// <param name="streamId">id of the stream</param>
        /// <param name="id">id of the payload within that stream</param>
        /// <param name="messages">List of messages associated</param>
        /// <returns></returns>
        protected Task<bool> OnReceived(string streamId, ulong id, Message[] messages)
        {
            var stream = _streamMappings.GetOrAdd(streamId, _ => new Linktionary<ulong, ScaleoutMapping>());

            var mapping = new ScaleoutMapping();
            stream.Add(id, mapping);

            foreach (var m in messages)
            {
                // Get the payload info
                var info = mapping.EventKeyMappings.GetOrAdd(m.Key, _ => new LocalEventKeyInfo());

                // Save the min and max for this payload for later
                ulong localId = Save(m);

                // Set the topic pointer for this event key so we don't need to look it up later
                info.Topic = _topics[m.Key];

                info.MinLocal = Math.Min(localId, info.MinLocal);
                info.Count++;
            }

            foreach (var eventKey in mapping.EventKeyMappings.Keys)
            {
                ScheduleEvent(eventKey);
            }

            return TaskAsyncHelper.True;
        }
Example #3
0
        internal static bool TryGetCommand(Message message, IJsonSerializer serializer, out SignalCommand command)
        {
            command = null;
            if (!message.SignalKey.EndsWith(SignalrCommand, StringComparison.OrdinalIgnoreCase))
            {
                return false;
            }

            command = message.Value as SignalCommand;

            // Optimization for in memory message store
            if (command != null)
            {
                return true;
            }

            // Otherwise deserialize the message value
            string rawValue = message.Value as string;
            if (rawValue == null)
            {
                return false;
            }

            command = serializer.Parse<SignalCommand>(rawValue);
            return true;
        }
        public Task Save(string key, object value)
        {
            var message = new Message(key, Interlocked.Increment(ref _lastMessageId), value);
            var list = _items.GetOrAdd(key, _ => new SafeSet<Message>());
            list.Add(message);

            return TaskAsyncHelper.Empty;
        }
Example #5
0
        protected internal Task Save(Message message)
        {
            var key = message.SignalKey;

            var list = _items.GetOrAdd(key, _ => new SafeSet<Message>());
            list.Add(message);

            if (message.Id > _lastMessageId) {
                lock (_idLocker) {
                    if (message.Id > _lastMessageId) {
                        _lastMessageId = message.Id;
                    }
                }
            }

            return TaskAsyncHelper.Empty;
        }
        protected internal Task Save(Message message)
        {
            var key = message.SignalKey;
            SafeSet<Message> list;
            if (!_items.TryGetValue(key, out list)) {
                list = new SafeSet<Message>();
                _items.TryAdd(key, list);
            }
            list.Add(message);
            if (message.Id > _messageId) {
                lock (_idLocker) {
                    if (message.Id > _messageId) {
                        _messageId = message.Id;
                    }
                }
            }

            return TaskAsyncHelper.Empty;
        }
 public Task Save(string key, object value)
 {
     var message = new Message(key, Interlocked.Increment(ref _lastMessageId), value);
     return Save(message);
 }
Example #8
0
        public Task Send(string eventKey, object value)
        {
            var list = _cache.GetOrAdd(eventKey, _ => new LockedList<Message>());

            Message message = null;

            try
            {
                // Take a write lock here so we ensure messages go into the list in order
                _cacheLock.EnterWriteLock();

                // Only 1 save allowed at a time, to ensure messages are added to the list in order
                message = new Message(eventKey, GenerateId(), value);
                _trace.Source.TraceInformation("MessageBus: Saving message {0} to cache", message.Id);
                list.AddWithLock(message);

                // Send to waiting callers.
                // This must be done in the read lock to ensure that messages are sent to waiting
                // connections in the order they were saved so that they always get the correct
                // last message id to resubscribe with.
                Broadcast(eventKey, message);
            }
            finally
            {
                _cacheLock.ExitWriteLock();
            }

            return TaskAsyncHelper.Empty;
        }
Example #9
0
 public static bool IsCommand(Message message)
 {
     return message.Key.EndsWith(SignalrCommand, StringComparison.OrdinalIgnoreCase);
 }
Example #10
0
        /// <summary>
        /// Publishes a new message to the specified event on the bus.
        /// </summary>
        /// <param name="source">A value representing the source of the data sent.</param>
        public virtual Task Publish(Message message)
        {
            Topic topic = GetTopic(message.Key);

            topic.Store.Add(message);

            _msgsTotalCounter.SafeIncrement();
            _msgsPerSecCounter.SafeIncrement();

            ScheduleTopic(topic);

            return TaskAsyncHelper.Empty;
        }
Example #11
0
        protected ulong Save(Message message)
        {
            Topic topic = GetTopic(message.Key);

            ulong id = topic.Store.Add(message);

            _msgsTotalCounter.SafeIncrement();
            _msgsPerSecCounter.SafeIncrement();

            return id;
        }
Example #12
0
        /// <summary>
        /// Publishes a new message to the specified event on the bus.
        /// </summary>
        /// <param name="source">A value representing the source of the data sent.</param>
        public virtual Task Publish(Message message)
        {
            Topic topic = GetTopic(message.Key);

            topic.Store.Add(message);

            _counters.MessageBusMessagesPublishedTotal.Increment();
            _counters.MessageBusMessagesPublishedPerSec.Increment();

            ScheduleTopic(topic);

            return TaskAsyncHelper.Empty;
        }
 /// <summary>
 /// Sends messages to the backplane
 /// </summary>
 /// <param name="messages"></param>
 /// <returns></returns>
 protected abstract Task Send(Message[] messages);
 public override Task Publish(Message message)
 {
     // TODO: Buffer messages here and make it configurable
     return Send(new[] { message });
 }
Example #15
0
        private bool ExcludeMessage(Message message)
        {
            if (String.IsNullOrEmpty(message.Filter))
            {
                return false;
            }

            string[] exclude = message.Filter.Split('|');

            return exclude.Any(signal => Identity.Equals(signal, StringComparison.OrdinalIgnoreCase) ||
                                                    _signals.Contains(signal) ||
                                                    _groups.Contains(signal));
        }
Example #16
0
        private Message CreateMessage(string key, object value)
        {
            var command = value as Command;
            var message = new Message(_connectionId, key, _serializer.Stringify(value));

            if (command != null)
            {
                // Set the command id
                message.CommandId = command.Id;
                message.WaitForAck = command.WaitForAck;
            }

            return message;
        }
Example #17
0
        protected ulong Save(Message message)
        {
            Topic topic = GetTopic(message.Key);

            ulong id = topic.Store.Add(message);

            _counters.MessageBusMessagesPublishedTotal.Increment();
            _counters.MessageBusMessagesPublishedPerSec.Increment();

            return id;
        }