2

I've run into some problems regarding rebus.

Here is my scenario. We have three services

Identity) published 'IdentityCreated' Message

Gateway) sends 'UpdateProfileCommand' directly into 'profile-westeu-input' queue

Profile) Consumes messages from input queue 'profile-westeu-input' and subscribes to 'IdentityCreated' messages

The rebus configuration seen in Profile Service

Given that i have registered my handlers with castle windsor.

container.Register(Classes.FromThisAssembly()
                  .BasedOn(typeof(IHandleMessages<>))
                  .WithServiceAllInterfaces()
                  .LifestyleTransient());

And i configured Rebus with

var bus = Configure.With(new CastleWindsorContainerAdapter(container))
            .Logging(x => x.Trace())
            .Transport(
                t => t.UseAzureServiceBus(connectionStringNameOrConnectionString: connectionString,
                        inputQueueAddress: ProfileInputQueueName, mode: AzureServiceBusMode.Standard))
            .Options(o => o.SimpleRetryStrategy(ProfileErrorQueueName))
            .Start();

and subscribed to a message type like this

bus.Subscribe(typeof(Nabufit.Messages.Identity.Events.IdentityCreated)).Wait()

I expected my handler was being called automatically. However it doesnt :(.

I've tried different solutions

  • Changed name of input queues
  • Created an eventemitter program, which published an event of the type 'IdentityCreated'. When looking in the input queue it is present but it doesnt get picked up by rebus.

Bonus info:

  • Using azure service bus
  • Hosting Rebus inside a Service fabric application
  • My input queue is named 'profile-westeu-input'
  • What happens? Does nothing happen at all? or do you get an exception saying that the message could not be dispatched to any handlers? – mookid8000 May 11 '16 at 14:31
  • Nope nothing at all. The latest information i get from rebus is that it have started 1 worker, and then silence from there on out. I can see that the the current build hasn't updated WindowsAzure.ServiceBus package in a while. I've updated the package locally, but doesn't seem to fix the issue. However, would you try to update to the latest, and run the test? – Martin Clausen May 11 '16 at 15:36
  • And heads up. We are running .net 4.6.1 which has some issues with the suggested version of WindowsAzure.ServiceBus package in rebus.azureservicebus. http://stackoverflow.com/questions/34329056/azure-webjobs-servicebus-returns-exception-found-2-dns-claims-in-authorization – Martin Clausen May 11 '16 at 15:39
  • Could you fire up Azure Service Bus Explorer and look at the topic? – mookid8000 May 11 '16 at 15:55
  • Iam not currently at the office, but if i recall correctly its listed under the message type with a subscriber which routes to profile_westeu_input? – Martin Clausen May 11 '16 at 15:58
  • that should be the case, yes :) – mookid8000 May 11 '16 at 17:13
  • Alright, so hosting the application in a console does seem to run fine, so i guess that the cookie trail is leading me down to service fabric. Ill investigate things further tommorrow, and i'll let you know what i find. However if you do have some suggestions, then they're more than welcome :) – Martin Clausen May 11 '16 at 19:44

1 Answers1

1

After investigating the application we found that we shared our Windsor Container between our Webapi in a OwinCommunicationListener, which had some custom lifetime configuration of dependencies. This caused two different error.

  1. Rebus not to pick up events, because of the containers configuration
  2. Architectural wise it not smart sharing the same container with the consuming process

We ended up building a custom ICommunicationListener specific for the bus consuming process using the build in BuiltinHandlerActivation class provided with rebus. to look something like this.

 public class ServiceBusCommunicationListener : ICommunicationListener
{
    private BuiltinHandlerActivator activator;

    public async Task<string> OpenAsync(CancellationToken cancellationToken)
    {
        activator = new BuiltinHandlerActivator();
        RegisterHandlers(activator);

        var connectionString = "...";
        var bus = Configure.With(activator)
            .Logging(x => x.Serilog(Log.Logger))
            .Transport(
                t => t.UseAzureServiceBus(connectionStringNameOrConnectionString: connectionString,
                        inputQueueAddress: "input", mode: AzureServiceBusMode.Standard))
            .Options(o => o.SimpleRetryStrategy("error"))
            .Start();

        return connectionString;
    }

    private void RegisterHandlers(BuiltinHandlerActivator builtinHandlerActivator)
    {
        (...)
    }

    public async Task CloseAsync(CancellationToken cancellationToken)
    {
        if (activator != null)
            activator.Dispose();
    }

    public void Abort()
    {
        if (activator != null)
            activator.Dispose();
    }
}

And registering the ServicebusCommunicationListner as a ServiceInstanceListener.

internal sealed class ProfileService : StatelessService
{
    public ProfileService(StatelessServiceContext context)
        : base(context)
    { }

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        return new[]
        {
            new ServiceInstanceListener(context => new ServiceBusCommunicationListener()), 
        };
    }
}
  • 2
    This will work when Rebus is hosted in a Stateless service, but when Rebus is hosted in a Statefull service, it is much better to configure and start Rebus in the Run method of the Statefull service. The reason is that during the Statefull service lifecycle, communication listeners are created in-between the execution of the service's Open and Run methods. Service Fabric provides no guarentee on having a StateManager in a valid state untill the Run method is executed, and hence any handlers triggering and expecting to work on the StateManager might not work untill the Run method is executed. – mikanyg Jul 01 '16 at 22:41