我怎么能有两个队列的rebus?

时间:2016-03-30 09:23:05

标签: ioc-container rebus

嗨我想要一个带有两个队列的rebus,这就是我现在配置它的方式

container.Register<BuiltinHandlerActivator>(() =>
        {
            var activator = new BuiltinHandlerActivator();               
            var rebusConnection = configuration["Rebus:ConnectionString"];
            activator.Register(() => ActivatorUtilities.CreateInstance<CampaignsHandler>(container));
            activator.Register(() => ActivatorUtilities.CreateInstance<MessageHandler>(container));
            activator.Register(() => ActivatorUtilities.CreateInstance<DeliveryStatusHandler>(container));
            Log.Logger = container.GetInstance<ILogger>();
            Configure.With(activator)
                .Transport(t => t.UseSqlServer(rebusConnection, "RebusQueue", "BackgroundJobs"))
                .Logging(l => l.Serilog(Log.Logger))
                .Routing(r =>
                {
                    var typeBasedRouting = r.TypeBased();
                    typeBasedRouting.MapAssemblyOf<MessageSent>("BackgroundJobs");                     

                })
                .Options(o => o.SetNumberOfWorkers(6))
                .Options(o => o.SetMaxParallelism(6))
                .Options(b => b.SimpleRetryStrategy(maxDeliveryAttempts: 1))
                .Start();               
            activator.Bus.Subscribe<MessageSent>().Wait();

            return activator;
        }, Lifestyle.Singleton);

我的MessageHandler处理了sendMessage对象并将它们转换为带有状态信息的messageSent obj,并且我的DeliveryStatusHandler处理了messageSent obj来更新我的数据库。 这个问题是我只有一个队列(一个数据库表&#34; RebusQueue&#34;)。所以只有在完成所有sendMessage对象之后,数据库才开始更新。

我想在处理sendMessage对象之后立即处理我的messageSent obj。所以我假设我应该有两个队列(两个表)?但是如何配置rebus?

我看了一下这个问题 Multiple input queues in one rebus process我们面临同样的问题吗?

这就是我在Messagehandler.cs中所做的事情

class MessageHandler : IHandleMessages<SendMessage>
{
    private readonly IBus _bus;
    private MessagingRuntime _messagingRuntime;
    private IRepository _repository;
    private ISnapshotRepository _snapshotRepository;
    private readonly ITemplateEngineProvider _templateEngineProvider;
    private IUrlShortener _urlShortener;
    private ILogger _logger;

    public MessageHandler(MessagingRuntime messagingRuntime, IRepository repository, ISnapshotRepository snapshotRepository, ITemplateEngineProvider templateEngineProvider, IUrlShortener urlShortener, IBus bus, ILogger logger)
    {
        _messagingRuntime = messagingRuntime;
        _repository = repository;
        _snapshotRepository = snapshotRepository;
        _templateEngineProvider = templateEngineProvider;
        _urlShortener = urlShortener;
        _bus = bus;
        _logger = logger;
    }

    public async Task Handle(SendMessage message)
    {
        var template = _snapshotRepository.Query<Template>(message.DateCreated).Where(x => x.Id == message.TemplateId).FirstOrDefault();
        var subscriber = _snapshotRepository.Query<Subscriber>(message.DateCreated).Where(x => x.Id == message.SubscriberId).FirstOrDefault();
        var templateEngine = GetTemplateEngine(message.CampaignId, message.Tags);


        var @event = new MessageSent
        {
            Id = SequentialGuid.Instance.NewGuid(),
            DeliveryStatusId = message.DeliveryStatusId,
            SubscriberId = subscriber.Id,
            DateCreated = message.DateCreated                
        };

        try
        {
            _messagingRuntime.ProcessSendRequest(new[] { subscriber }, templateEngine, template);
            @event.IsDeliverySuccessful = true;
        }
        catch (MessagingException ex)
        {
            _logger.Error(ex.ToString());
            @event.IsDeliverySuccessful = false;
        }

        await _bus.Publish(@event);
    }
}

这是第二个处理程序(更新数据库)

class DeliveryStatusHandler : IHandleMessages<MessageSent>
{
    private ILogger _logger;
    private IRepository _repository;
    private IRepository2 _repository2;
    private ISnapshotRepository _snapshotRepository;

    public DeliveryStatusHandler(IRepository repository, IRepository2 repository2,ISnapshotRepository snapshotRepository, ILogger logger)
    {
        _repository = repository;
        _repository2 = repository2;
        _snapshotRepository = snapshotRepository;
        _logger = logger;
    }

    public Task Handle(MessageSent @event)
    {
        var deliveryStatus = _repository2.Find<DeliveryStatus>(@event.DeliveryStatusId);
        if (deliveryStatus == null)
        {
            _logger.Error("Delivery Status does not exist");
            return Task.FromResult<object>(null);
        }

        var deliveryStatusItem = _repository2.Find<DeliveryStatusItem>(@event.Id);
        var subscriber = _snapshotRepository.Query<Subscriber>(@event.DateCreated).Where(x => x.Id == @event.SubscriberId).FirstOrDefault();
        if (deliveryStatusItem == null)
        {
            deliveryStatusItem = new DeliveryStatusItem();
            deliveryStatusItem.Id = @event.Id;
            deliveryStatusItem.Email = subscriber.Email;
            deliveryStatusItem.PhoneNumber = subscriber.PhoneNumber;
            deliveryStatusItem.Name = subscriber.Name;

        }
        deliveryStatusItem.DeliveryStatusId = @event.DeliveryStatusId;
        deliveryStatusItem.IsDeliverySuccessful = @event.IsDeliverySuccessful;
        _repository2.Save<DeliveryStatusItem>(deliveryStatusItem);
        return Task.FromResult<object>(null);
    }
}

1 个答案:

答案 0 :(得分:2)

如果我是你,我会启动两个Rebus实例,每个实例都有自己的输入队列(如果你不需要彼此独立地更新它们,那么在同一个过程中完成它是完全没问题的)。

这两个例子是:

  1. 你带给我的处理程序的第一个
  2. 第二个将订阅MessageSent并相应处理
  3. 的人

    通过这种方式,您可以轻松配置每个实例的线程数和并行度设置,从而可以限制/缩放消息的处理。