Re: [masstransit-discuss] Mass Transit -> SignalR bridge

653 views
Skip to first unread message

Dru Sellers

unread,
Feb 27, 2013, 5:47:21 PM2/27/13
to masstrans...@googlegroups.com


On Wed, Feb 27, 2013 at 1:44 PM, Josh Bush <josh...@gmail.com> wrote:
I'm working on a project with MassTransit publishing events (via RabbitMQ) that we denormalize into read models. Once a read model is generated/updated I publish another message that needs to make it to the client to update the UI. Enter SignalR.  I had stupidly registered the handlers as lambdas in the hub constructor and quickly discovered that there are a lot of hub instances set up. :face palm:

I think what I'm looking for is the web server(s) to be subscribed in a non-durable fanout exchange. A quick twitter conversation with Chris revealed that I need to mark those consumers as transient. https://twitter.com/PhatBoyG/status/306831977770790913

Now, onto the questions:

If this is the way to go, is there a way to configure all consumers registered in my container as transient? Every handler that my web instance declares would be transient.

I would suggest implementing your own 'scan' method that does this. its not a lot of code to do and would give you the level of control you want
 

I could be barking up the wrong tree with this approach from the get go. It looks like if I have multiple web servers each one needs to have it's own queue. Does anyone have any recommendations how this might work in a cloud environment where nodes can get spun up and down? It feels like I need a way to specify that the web server's queues are temporary.

rabbitmq has a temporary queue name concept, that we probably don't easily expose but could. then there is another switch in rabbitmq i believe that will tear down the bindings when it goes away. Might be interesting.
 

Chris also recommended that I look at the SignalR backplane bits. With this approach, I wouldn't need any of the above. Instead, I could register the consumers on my worker like normal and poke the messages into SignalR endpoint via the c# client. I know the signalR scale out stuff is relatively new. I'm hoping someone might have some direction for me as to which direction I might want to take this.

all chris here
 

Thank You,
Josh

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.
To post to this group, send email to masstrans...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/masstransit-discuss/-/kTXUzb7P61cJ.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Travis Smith

unread,
Feb 27, 2013, 8:06:36 PM2/27/13
to masstrans...@googlegroups.com
I feel like with a lot of transient queues, subscriptions, you'll end up with a lot of junk that for some edge case doesn't get cleaned up. Over time this could be problematic. It is likely solvable, but doesn't mean it's easy. 

I don't know anything about SIgnalR, so I'm not help in regards to that. Well, I know what it is, but I haven't even looked at it. 

-Travis

Josh Bush

unread,
Feb 27, 2013, 8:23:38 PM2/27/13
to masstrans...@googlegroups.com
Am I going about this the wrong way? If I'm heading down a painful path, I'd like to know sooner than later. :)

Josh


On Wednesday, February 27, 2013 7:06:36 PM UTC-6, Travis Smith wrote:
I feel like with a lot of transient queues, subscriptions, you'll end up with a lot of junk that for some edge case doesn't get cleaned up. Over time this could be problematic. It is likely solvable, but doesn't mean it's easy. 

I don't know anything about SIgnalR, so I'm not help in regards to that. Well, I know what it is, but I haven't even looked at it. 

-Travis


On Wed, Feb 27, 2013 at 5:47 PM, Dru Sellers <d...@drusellers.com> wrote:
On Wed, Feb 27, 2013 at 1:44 PM, Josh Bush <josh...@gmail.com> wrote:
I'm working on a project with MassTransit publishing events (via RabbitMQ) that we denormalize into read models. Once a read model is generated/updated I publish another message that needs to make it to the client to update the UI. Enter SignalR.  I had stupidly registered the handlers as lambdas in the hub constructor and quickly discovered that there are a lot of hub instances set up. :face palm:

I think what I'm looking for is the web server(s) to be subscribed in a non-durable fanout exchange. A quick twitter conversation with Chris revealed that I need to mark those consumers as transient. https://twitter.com/PhatBoyG/status/306831977770790913

Now, onto the questions:

If this is the way to go, is there a way to configure all consumers registered in my container as transient? Every handler that my web instance declares would be transient.

I would suggest implementing your own 'scan' method that does this. its not a lot of code to do and would give you the level of control you want
 

I could be barking up the wrong tree with this approach from the get go. It looks like if I have multiple web servers each one needs to have it's own queue. Does anyone have any recommendations how this might work in a cloud environment where nodes can get spun up and down? It feels like I need a way to specify that the web server's queues are temporary.

rabbitmq has a temporary queue name concept, that we probably don't easily expose but could. then there is another switch in rabbitmq i believe that will tear down the bindings when it goes away. Might be interesting.
 

Chris also recommended that I look at the SignalR backplane bits. With this approach, I wouldn't need any of the above. Instead, I could register the consumers on my worker like normal and poke the messages into SignalR endpoint via the c# client. I know the signalR scale out stuff is relatively new. I'm hoping someone might have some direction for me as to which direction I might want to take this.

all chris here
 

Thank You,
Josh

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.

To post to this group, send email to masstrans...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/masstransit-discuss/-/kTXUzb7P61cJ.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.

Travis Smith

unread,
Feb 27, 2013, 8:47:39 PM2/27/13
to masstrans...@googlegroups.com
Cleaning up leftover transient queues/exchanges could just be a process that runs regularly, looking at what machines are active in your cloud. There's APIs on Azure and AWS to access this stuff, and I assume any other cloud provider you might be using. So it's possible to address as needed. When I've run stuff on AWS I would get alerts sometimes that boxes stopped responding and they would just be totally dead. I would kill it and spin up a new one. Why we clustered everything ;) It will happen, stuff won't get cleaned up since it didn't shutdown properly. Just have your janitor do that work if needed. So I don't want to dissuade you from your current approach if you feel like you're heading down the right path. And remember, the MVP doesn't need the janitor (I assume), if it gets bad clean it up manually. Once you do that, then it's time to actually get the janitor written. 

We're at a point where a couple new RabbitMQ releases and SignalR releases we could be in a totally new spot. I would focus on what you feel like gets you where you need to be over what might be best over the long term. Or just write your app in Erlang ;) 

-Travis


To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.

To post to this group, send email to masstrans...@googlegroups.com.

Eugene Tolmachev

unread,
Feb 28, 2013, 12:18:38 PM2/28/13
to masstrans...@googlegroups.com
We have it all working rather well, albeit with a single IIS machine. I don't think it will be any problem to extend to a load-balanced farm, due to RabbitMQ clustering we employ, with each service talking to a local rabbit node, including ASP.NET.

This is outline of the service we have running in that ASP worker process:

    public class NotificationService : PersistentConnection, 
        IStartable,
        Consumes<ObjectUpdatedNotification>.All
   {
        IConnectionManager _connectionManager;

        public NotificationService(IConnectionManager connectionManager)
        {
            _connectionManager = connectionManager;
        }

        #region SignalR handlers
        protected override Task OnConnectedAsync(IRequest request, IEnumerable<string> groups, string connectionId)
        {
            //{0} connected as {1}, mapped to {2}", connectionId, HttpContext.Current.User.Identity.Name, customerId
            //map identity to customerId
            return AddCustomerConnection(customerId);
        } 
        #endregion

        #region MassTransit Consumes
        public void Consume(ObjectUpdatedNotification message)
        {
            Notify(message);
        } 
        #endregion

        #region Startable
        public void Start()
        {
            RouteTable.Routes.MapConnection<NotificationService>("notification", "notification/{*operation}");
        }

        public void Stop()
        {
        } 
        #endregion

        void Notify(IObjectNotification message)
        {
            if (message.CustomerId.HasValue)
                _connectionManager
                    .GetConnection<NotificationService>()
                    .Broadcast(ToGroupName(message.CustomerId.Value), JsonConvert.SerializeObject(message.ToNotification()));
        }

        string ToGroupName(Guid customerId)
        {
            return GetType().FullName + "." + customerId;
        }
    
        Task AddCustomerConnection(Guid customerId)
        {
            return Connection.SendCommand(new SignalCommand
            {
                Type = CommandType.AddToGroup,
                Value = ToGroupName(customerId)
            });
        }
    }

A Silverlight client listening on the other end.

Jeffrey T. Fritz

unread,
Feb 28, 2013, 12:23:26 PM2/28/13
to masstrans...@googlegroups.com
Just use the RabbitMQ - SignalR backplane.

No need to MT in that model... just publish a message to SignalR client using a standard Hub or PersistentConnection.



Jeff



--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.
To post to this group, send email to masstrans...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages