Skip to content

Support for IConsumerDefinition ? #44

Description

@wokket

G'day again,

Another request/discussion rather than bug... We currently make heavy use of MassTransit's IConsumerDefinition type to keep all the per-consumer configuration (retry/redelivery logic, concurrent processing limits, whether to throw Fault, support skipped etc) nice and close to the consumer, rather than having to touch our mass transit installer helper every time we add a consumer (which also reduces merge conflicts)...

public sealed class ElidedConsumerDefinition : ConsumerDefinition<ElidedConsumer>
{
	protected override void ConfigureConsumer(IReceiveEndpointConfigurator endpointConfigurator, IConsumerConfigurator<ElidedConsumer> consumerConfigurator, IRegistrationContext context)
	{
		endpointConfigurator.PrefetchCount = 100; // no point prefetching less than a full batch size or we'll just timeout.
		endpointConfigurator.ConcurrentMessageLimit = 100;

		consumerConfigurator.Options<BatchOptions>(options => options
			.SetMessageLimit(100)
			.SetTimeLimit(TimeSpan.FromSeconds(1))
			.SetConcurrencyLimit(1)); // don't add unnecessary database load by running concurrently
	}
}

public sealed class ElidedConsumer : IConsumer<MyMessageType> 
{ ... }

Is support for something like this something you'd consider, either as a separate type, or an optional static method on the IConsumer or something??

In a perfect world we'd be able to do all the topology/bus configuration for this from the one place given we don't do any custom endpoint naming etc in MT, it's strictly one endpoint per consumer, with queues/exchanges all created/named by MT.

If you're open to the idea I was thinking about prototyping something similar to:

public class ElidedConsumerDefinition : MTKebabCasedConsumerDefinition<ElidedConsumer>  // MT to indicate we want back-compat defaults
{
   protected override void ConfigureConsumer(Action<IQueueConfigurator> ??,  ...) {
      ...
  }

   protected override void ConfigureEndpoint(Action<IEndpointConfigurator> ??,  ...) {
      ...
  }

}

That would:

  • declare the my-namespace-elided-consumer Exchange and Queue in the topology bound together (topology.DeclareExchange, topology.DeclareQueue and topology.BindExchangeToQueue)
  • declare the MT compatible exchanges for MyMessageType
  • create the receive endpoint for the consumer, and call e.Consumer<ElidedConsumer, MyMessageType>
    • As an aside, it feels awkward to have to pass the message type here when the IConsumer already declares the message types it supports, is there a perf-related reason for this?)
  • apply the endpoint configuration re: concurrency, deadletters etc

Any thoughts? This is pretty rough and a. have no idea how plausible it is, and b. could no doubt be improved with smarter neurons.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions