mt3 extension points

64 views
Skip to first unread message

Egor Chikunov

unread,
Aug 28, 2015, 9:42:42 AM8/28/15
to masstransit-discuss
Hello, everyone!

I'm trying to implement couple things and need an advice about masstransit-y way to do that.

1. In 2 version there was IConsume<>.All interface that allowed to have Consume methods without ConsumeContext<> parameter. 
How can I achieve same behavior in 3 version? The reason is simple: I've got batch messages, that can contain multiple messages. At the same time messages may come one by one. 
So in case of the batch I'm just calling consumer methods manually, passing appropriate child messages from the batch.

2. I'm going to implement message reordering and dependency checking (for instance, message from one source should be processed after the message from other source).
What is the best place to extend masstransit to achieve that?

3. What's the recommended way to use sagas in mt3? Using MassTransitStateMachine?

Chris Patterson

unread,
Aug 28, 2015, 11:00:22 AM8/28/15
to masstrans...@googlegroups.com
You could put the consumer behavior in a separate class that  is used by both the batch and the single message consumer. That way, the consumer construct (which is very similar to a web api controller) is separated from the actual message processing behavior. Then each consume method just calls the class with the per-message behavior.


--
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/msgid/masstransit-discuss/53a874f3-f01e-4b0c-9bc1-b14e2f5518da%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Egor Chikunov

unread,
Aug 28, 2015, 11:21:29 AM8/28/15
to masstransit-discuss
That was my first idea. But that way I'll end up with a lot of consume methods looking just the same - get message from consumecontext and pass it to processor

пятница, 28 августа 2015 г., 18:00:22 UTC+3 пользователь Chris Patterson написал:
You could put the consumer behavior in a separate class that  is used by both the batch and the single message consumer. That way, the consumer construct (which is very similar to a web api controller) is separated from the actual message processing behavior. Then each consume method just calls the class with the per-message behavior.

On Fri, Aug 28, 2015 at 6:42 AM, Egor Chikunov <chikun...@gmail.com> wrote:
Hello, everyone!

I'm trying to implement couple things and need an advice about masstransit-y way to do that.

1. In 2 version there was IConsume<>.All interface that allowed to have Consume methods without ConsumeContext<> parameter. 
How can I achieve same behavior in 3 version? The reason is simple: I've got batch messages, that can contain multiple messages. At the same time messages may come one by one. 
So in case of the batch I'm just calling consumer methods manually, passing appropriate child messages from the batch.

2. I'm going to implement message reordering and dependency checking (for instance, message from one source should be processed after the message from other source).
What is the best place to extend masstransit to achieve that?

3. What's the recommended way to use sagas in mt3? Using MassTransitStateMachine?

--
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.

Chris Patterson

unread,
Aug 28, 2015, 12:08:33 PM8/28/15
to masstrans...@googlegroups.com
Would you not expect to unit test the behavior of the consumer outside of actually sending it as a message?

I guess you could just have two Consume() methods in your consumer (one for single, one for batch) and then have a private method ConsumeMessage(ConsumeContext context, TMessage message) that is called for each individual message.

On Fri, Aug 28, 2015 at 8:21 AM, Egor Chikunov <chikun...@gmail.com> wrote:
That was my first idea. But that way I'll end up with a lot of consume methods looking just the same - get message from consumecontext and pass it to processor

пятница, 28 августа 2015 г., 18:00:22 UTC+3 пользователь Chris Patterson написал:
You could put the consumer behavior in a separate class that  is used by both the batch and the single message consumer. That way, the consumer construct (which is very similar to a web api controller) is separated from the actual message processing behavior. Then each consume method just calls the class with the per-message behavior.

On Fri, Aug 28, 2015 at 6:42 AM, Egor Chikunov <chikun...@gmail.com> wrote:
Hello, everyone!

I'm trying to implement couple things and need an advice about masstransit-y way to do that.

1. In 2 version there was IConsume<>.All interface that allowed to have Consume methods without ConsumeContext<> parameter. 
How can I achieve same behavior in 3 version? The reason is simple: I've got batch messages, that can contain multiple messages. At the same time messages may come one by one. 
So in case of the batch I'm just calling consumer methods manually, passing appropriate child messages from the batch.

2. I'm going to implement message reordering and dependency checking (for instance, message from one source should be processed after the message from other source).
What is the best place to extend masstransit to achieve that?

3. What's the recommended way to use sagas in mt3? Using MassTransitStateMachine?

--
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.

--
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.

Egor Chikunov

unread,
Aug 28, 2015, 12:24:05 PM8/28/15
to masstransit-discuss
I guess I wasn't clear enough... Here is the example of what I'm talking about:
internal class StorageCommandsHandler :
IConsumer<CreateStorage>,
IConsumer<EnableStorage>,
IConsumer<DisableStorage>
{

public Task Consume(IConsumeContext<CreateStorage> message)
{
var command = message.Message;
Process(command);
return Task.FromResult(0);
}

public Task Consume(IConsumeContext<DisableStorage> message)
{
var command = message.Message;
Process(command);
return Task.FromResult(0);
}

public Task Consume(IConsumeContext<EnableStorage> message)
{
var command = message.Message;
Process(command);
return Task.FromResult(0);
}

public void Process(CreateStorage)
{
// Do actual stuff
}

public void Process(EnableStorage)
{
// Do actual stuff
}

public void Process(DisableStorage)
{
// Do actual stuff
}
}

So there is a lot of Consume() boilerplate code for every commandHandler


пятница, 28 августа 2015 г., 19:08:33 UTC+3 пользователь Chris Patterson написал:
Would you not expect to unit test the behavior of the consumer outside of actually sending it as a message?

I guess you could just have two Consume() methods in your consumer (one for single, one for batch) and then have a private method ConsumeMessage(ConsumeContext context, TMessage message) that is called for each individual message.
On Fri, Aug 28, 2015 at 8:21 AM, Egor Chikunov <chikun...@gmail.com> wrote:
That was my first idea. But that way I'll end up with a lot of consume methods looking just the same - get message from consumecontext and pass it to processor

пятница, 28 августа 2015 г., 18:00:22 UTC+3 пользователь Chris Patterson написал:
You could put the consumer behavior in a separate class that  is used by both the batch and the single message consumer. That way, the consumer construct (which is very similar to a web api controller) is separated from the actual message processing behavior. Then each consume method just calls the class with the per-message behavior.

On Fri, Aug 28, 2015 at 6:42 AM, Egor Chikunov <chikun...@gmail.com> wrote:
Hello, everyone!

I'm trying to implement couple things and need an advice about masstransit-y way to do that.

1. In 2 version there was IConsume<>.All interface that allowed to have Consume methods without ConsumeContext<> parameter. 
How can I achieve same behavior in 3 version? The reason is simple: I've got batch messages, that can contain multiple messages. At the same time messages may come one by one. 
So in case of the batch I'm just calling consumer methods manually, passing appropriate child messages from the batch.

2. I'm going to implement message reordering and dependency checking (for instance, message from one source should be processed after the message from other source).
What is the best place to extend masstransit to achieve that?

3. What's the recommended way to use sagas in mt3? Using MassTransitStateMachine?

--
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.

--
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.

Egor Chikunov

unread,
Aug 28, 2015, 12:27:25 PM8/28/15
to masstransit-discuss
Wow, that 'code' tag really made everything look strange o,o
Sorry, i'm not very familiar with google groups

Luke Usher

unread,
Sep 8, 2015, 2:15:57 AM9/8/15
to masstransit-discuss
You can create a wrapper class like this:

public class ConsumerWrapper<TMessageType>
: IConsumer<TMessageType> where TMessageType : class {

private readonly IHandle<TMessageType> Handler;
private readonly ILogger Log;

public ConsumerWrapper(IHandle<TMessageType> handler, ILogger log) {
Handler = handler;
Log = log;
}

public Task Consume(ConsumeContext<TMessageType> context) {

try {
Log.Message("Handling message of Type '{0}'", typeof(TMessageType).Name);
Handler.Consume(context.Message);
}
catch(Exception e) {
Log.Exception(e);
}
return Task.CompletedTask;
}
}

Then the wrapper is registered as the consumer, the wrapper handles the context etc, The actual message is passed to an IHandle, which only knows the message type. 
Reply all
Reply to author
Forward
0 new messages