How to Send(T message)

2,339 views
Skip to first unread message

yreynhout

unread,
May 2, 2012, 6:53:59 AM5/2/12
to masstrans...@googlegroups.com
Hi,

simple newbie Q: How do I resolve the endpoint to send a given message type to without resorting to putting hard-coded Uri's in my code (or having custom config ripple up to the "sender") ?
I found some mention of it here, but it seems a tad out-dated since IEndpointResolver is not even a type anymore (in 2.5.0 pre-release). I presume it got replaced by IEndpointCache on the bus. The only thing that somewhat "smells" like that functionality is bus.OutboundPipeline.Dispatch<TMessage>(..); but I doubt that's the right direction. 
http://readthedocs.org/docs/masstransit/en/latest/configuration/gotchas.html?highlight=send 

To be clear, I don't want to publish, I want to send. Maybe I'm thrown off by the Publish method on the bus (which triggers pub/sub for "event" style messages in my mind). I'd like to hear an answer in case of both dynamic and static routing. I'm stuck with MSMQ (so don't try to sell me a rabbit in a hat).

Regards,
Yves.

yreynhout

unread,
May 2, 2012, 8:55:20 AM5/2/12
to masstrans...@googlegroups.com
Just to add to that: Is masstransit opnionated about Send vs Publish or does it simply not care (compared to e.g. NSB)? Why would one use the former vs the latter? As far as I've understood Publish routes messages types based on known subscriptions, whereas Send routes messages to the endpoint it is invoked on.

Regards,
Yves.

Dru Sellers

unread,
May 2, 2012, 9:08:25 AM5/2/12
to masstrans...@googlegroups.com
To send:

bus.GetEndpoint(new Uri("msmq://localhost/thequeue")).Send(msg);

Publish is a broadcast, it will go to all subscribers
Send is point to point it goes to one person even if others are subscribed.

What I hear you saying you want is

bus.Send(msg)

If that is correct, where would it go?

-d

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To view this discussion on the web visit https://groups.google.com/d/msg/masstransit-discuss/-/-5TMFLD2SUsJ.

To post to this group, send email to masstrans...@googlegroups.com.
To unsubscribe from this group, send email to masstransit-dis...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/masstransit-discuss?hl=en.

Chris Patterson

unread,
May 2, 2012, 9:15:18 AM5/2/12
to masstrans...@googlegroups.com
Opinions are great, when you agree with them.

As always, it depends.

If you are capturing data for processing by a service, sending a command, or any of those point-to-point things, send is your best friend. You can find an endpoint using the bus.GetEndpoint(uri) method, and then call Send() on that interface (IEndpoint). That will serialize and send the message directly to that endpoint without any additional processing.

Publish is a convention-based method of publishing a message (be it an event, a command, whatever - we don't distinguish in the framework). In MassTransit, messages are publishing and subscribed by types (since we're in C#, and it's a static language). If you want to get technical, the type could be an analog to a "topic" in other systems, but topics are more of a routing concern, whereas types are a message contract concern.

When you subscribe on a bus instance, you are telling the bus that you are interested in messages of type T. T can be a class or an interface (in fact, interfaces are recommended since they evolve more nicely over time). Any messages received by that bus instance that match the type you subscribed to (whether they were sent directly to the endpoint Uri or routed by convention after being published) will be delivered to your message handler/consumer/saga/instance.




On Wed, May 2, 2012 at 7:55 AM, yreynhout <yves.r...@gmail.com> wrote:
--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.

yreynhout

unread,
May 2, 2012, 9:50:17 AM5/2/12
to masstrans...@googlegroups.com
It would go to the logical address that message type represents. I figured the {message type, Uri} mapping would be set up somewhere else, not as part of the code resolving the endpoint and invoking the send (which would force me down the road of hardcoding or taking care of it myself using custom configuration). Maybe it was naive of me to expect this kind of behavior to be in the box and not muck around with Uri's in my code. Especially, since this is the kind of thing an ops team should be able to rearrange.

What would be the proper extensibility point to start building such a feature?


On Wednesday, May 2, 2012 3:08:25 PM UTC+2, Dru wrote:
To send:

bus.GetEndpoint(new Uri("msmq://localhost/thequeue")).Send(msg);

Publish is a broadcast, it will go to all subscribers
Send is point to point it goes to one person even if others are subscribed.

What I hear you saying you want is

bus.Send(msg)

If that is correct, where would it go?

-d

On Wed, May 2, 2012 at 7:55 AM, yreynhout <> wrote:
Just to add to that: Is masstransit opnionated about Send vs Publish or does it simply not care (compared to e.g. NSB)? Why would one use the former vs the latter? As far as I've understood Publish routes messages types based on known subscriptions, whereas Send routes messages to the endpoint it is invoked on.

Regards,
Yves.

On Wednesday, May 2, 2012 12:53:59 PM UTC+2, yreynhout wrote:
Hi,

simple newbie Q: How do I resolve the endpoint to send a given message type to without resorting to putting hard-coded Uri's in my code (or having custom config ripple up to the "sender") ?
I found some mention of it here, but it seems a tad out-dated since IEndpointResolver is not even a type anymore (in 2.5.0 pre-release). I presume it got replaced by IEndpointCache on the bus. The only thing that somewhat "smells" like that functionality is bus.OutboundPipeline.Dispatch<TMessage>(..); but I doubt that's the right direction. 
http://readthedocs.org/docs/masstransit/en/latest/configuration/gotchas.html?highlight=send 

To be clear, I don't want to publish, I want to send. Maybe I'm thrown off by the Publish method on the bus (which triggers pub/sub for "event" style messages in my mind). I'd like to hear an answer in case of both dynamic and static routing. I'm stuck with MSMQ (so don't try to sell me a rabbit in a hat).

Regards,
Yves.

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To view this discussion on the web visit https://groups.google.com/d/msg/masstransit-discuss/-/-5TMFLD2SUsJ.

To post to this group, send email to masstransit-discuss@googlegroups.com.
To unsubscribe from this group, send email to masstransit-discuss+unsub...@googlegroups.com.

Dru Sellers

unread,
May 2, 2012, 9:58:52 AM5/2/12
to masstrans...@googlegroups.com
What I am hearing is a desire for a 'virtual address' its something I have toyed w/ implementing, and is easily built using just config files.

you want bus.Send(msg)
- in that send message a look up needs to be done
- assumes that each message type only has one consumer
- inside the send you just look up the uri by message type
- then call the original send with uri and message

does that make sense?

-d

To view this discussion on the web visit https://groups.google.com/d/msg/masstransit-discuss/-/3GCXaApfAMcJ.

To post to this group, send email to masstrans...@googlegroups.com.
To unsubscribe from this group, send email to masstransit-dis...@googlegroups.com.

Chris Patterson

unread,
May 2, 2012, 10:01:29 AM5/2/12
to masstrans...@googlegroups.com
Message Type -> Uri is there, it's called Publish, and it's by convention.

Maybe I am not understanding what you are trying to do.

On Wed, May 2, 2012 at 8:50 AM, yreynhout <yves.r...@gmail.com> wrote:
To view this discussion on the web visit https://groups.google.com/d/msg/masstransit-discuss/-/3GCXaApfAMcJ.

To post to this group, send email to masstrans...@googlegroups.com.
To unsubscribe from this group, send email to masstransit-dis...@googlegroups.com.

yreynhout

unread,
May 2, 2012, 10:05:51 AM5/2/12
to masstrans...@googlegroups.com
Exactly.


On Wednesday, May 2, 2012 3:58:52 PM UTC+2, Dru wrote:
What I am hearing is a desire for a 'virtual address' its something I have toyed w/ implementing, and is easily built using just config files.

you want bus.Send(msg)
- in that send message a look up needs to be done
- assumes that each message type only has one consumer
- inside the send you just look up the uri by message type
- then call the original send with uri and message

does that make sense?

-d
-d


To unsubscribe from this group, send email to masstransit-discuss+unsubscribe...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/masstransit-discuss?hl=en.

Chris Patterson

unread,
May 2, 2012, 10:11:25 AM5/2/12
to masstrans...@googlegroups.com
You can also using the RoutingService to do this stuff, binding types to Uris with code.

To view this discussion on the web visit https://groups.google.com/d/msg/masstransit-discuss/-/3St-2IY-wM0J.

To post to this group, send email to masstrans...@googlegroups.com.
To unsubscribe from this group, send email to masstransit-dis...@googlegroups.com.

yreynhout

unread,
May 2, 2012, 10:14:47 AM5/2/12
to masstrans...@googlegroups.com
I guess you are right too. Just wish it were called Send and ensures exactly one Uri associated with the message type (point to point).
I realize I could just use Publish (feels wrong for what is essentialy p-t-p) or use an explicit send endpoint uri in my own code (or via my own config).

I'll take a look at the RoutingService as per your suggestion.

Thanks.

On Wednesday, May 2, 2012 4:01:29 PM UTC+2, Chris Patterson wrote:
Message Type -> Uri is there, it's called Publish, and it's by convention.

Maybe I am not understanding what you are trying to do.

-d


To unsubscribe from this group, send email to masstransit-discuss+unsubscribe...@googlegroups.com.
-d


To unsubscribe from this group, send email to masstransit-discuss+unsubscribe...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/masstransit-discuss?hl=en.

Dru Sellers

unread,
May 2, 2012, 10:29:26 AM5/2/12
to masstrans...@googlegroups.com
Ok, so here is my suggestion for you.

Add an Extension Method to IServiceBus like:

public static void Send<T>(this IServiceBus bus, T message)
{
     var uri = DoLookup<T>();
     bus.GetEndpoint(uri).Send(message);
}


Easy peasy.

-d

To view this discussion on the web visit https://groups.google.com/d/msg/masstransit-discuss/-/c-NreP93-tcJ.

To post to this group, send email to masstrans...@googlegroups.com.
To unsubscribe from this group, send email to masstransit-dis...@googlegroups.com.

Martin Nilsson

unread,
May 30, 2012, 1:36:22 PM5/30/12
to masstrans...@googlegroups.com
Is it possible to make sure that there are someone listening when doing bus.GetEndpoint(uri).Send(message)?
I'm sending commands to this endpoint and don't want a fire and forget for this. I'm using RabbitMQ as a transport.

//martin

Dru Sellers

unread,
May 30, 2012, 2:21:27 PM5/30/12
to masstrans...@googlegroups.com
By default. In MT. No. 

What is it that you would like to achieve? Maybe I can help you find a solution. 

-d

Martin Nilsson

unread,
May 30, 2012, 2:33:18 PM5/30/12
to masstrans...@googlegroups.com
I want for example a RegisterPaymentCommand to have a consumer and if it hasn't then fail the operation. 
To make sure it's not lost.

Maybe I can do something with a RabbitMQ direct exchange?

Dru Sellers

unread,
May 30, 2012, 2:40:30 PM5/30/12
to masstrans...@googlegroups.com
Ok,

so we SEND RegisterPaymentCommand
some point later a consumer will get the message and process it. it could then publish an Event (or Respond to the request) saying it was successful or not.
The sender can keep a time out going so that if it doesn't receive a response in, say 5 seconds, it can take a different action.

????

This kind of approach would be more inline with an async / message based approach.

-d

Martin Nilsson

unread,
May 30, 2012, 3:58:59 PM5/30/12
to masstrans...@googlegroups.com
What if the consumer process is down for 1 h? Should I send a new register command or notify the user after x number of retries that she can not pay for the moment?

If I could know that there was a receiver then I would know that it would be delivered to a consumer because of guaranteed delivery.

Dru Sellers

unread,
May 30, 2012, 5:30:52 PM5/30/12
to masstrans...@googlegroups.com
Ok, so this is different.

Do you want to know if there is a 'Receiver' or a 'Subscriber' ?

As long as someone is subscribed you won't lose the message.

-d

Dru Sellers

unread,
May 30, 2012, 5:36:33 PM5/30/12
to masstrans...@googlegroups.com
If the consumer process, is down for 1hr that's ok. As long as there is a subscription registered it will be delivered to the consumer's queue. When the process comes back online it will get the message and go on its way.

-d

Martin Nilsson

unread,
May 30, 2012, 5:41:44 PM5/30/12
to masstrans...@googlegroups.com
"As long as there is a subscription registered"

But if there isn't anyone registered? That's my point :)

Sent from my iPad

Dru Sellers

unread,
May 30, 2012, 5:51:04 PM5/30/12
to masstrans...@googlegroups.com
Well, this is where I say. "Its your system. Why wouldn't there be?"

-d

Martin Nilsson

unread,
May 31, 2012, 1:42:18 AM5/31/12
to masstrans...@googlegroups.com
Well, sometimes we have bugs and configuration errors in our system. :) Also, distributed programming is already hard as it is for an average developer so any guards in the system will help us to not lose important messages.

I hear what you are saying and will try to find another solution then.

Dru Sellers

unread,
May 31, 2012, 6:10:11 PM5/31/12
to masstrans...@googlegroups.com
agreed, since subscriptions are usually pretty static (assuming permanent subscriptions) its not usually too big of a deal. That said, we have system view (which doesn't work well [by that I mean at all]) with RabbitMQ. but RabbitMQ has the management dashboard that you can visually inspect to ensure things are good.


-d

Henrik Feldt

unread,
Jun 3, 2012, 9:34:30 AM6/3/12
to masstrans...@googlegroups.com

RabbitMQ supports the required flag.

I think we should allow for a transport specific configurator in the Action<IPublishContext<T>>. If you send a pull request I will review it.

Martin Nilsson

unread,
Jun 3, 2012, 1:41:28 PM6/3/12
to masstrans...@googlegroups.com
Ok, I didn't know that.
I think it's possible to do for MSMQ transport as well because this behavior exists in Rhino ESB.

"Notify & Publish are very similar, both of them will publish the message to all interested subscribers, but they have one very different semantic. If you publish a message and it has no subscribers, it is considered an error, and it will throw. If you you use notify, it is expected that you might not have any subscribers. I find this distinction important enough that I wanted to capture this in the API."

I'm not sure I'm capable of creating this feature in MT though. And I don't expect you to do it either. But when I know more about the details of MT I might give it a try. 

Henrik Feldt

unread,
Jun 7, 2012, 1:01:07 PM6/7/12
to masstrans...@googlegroups.com

The subscription service could probably be configured pretty easily to send a message to any app that published to the void...

Reply all
Reply to author
Forward
0 new messages