2016-03-03 1 views
1

J'utilise la dernière version de Rebus (0.99.35) avec SimpleInjector (3.1.2). Dans mon premier exemple de projet, j'utilise SQL Server pour le transport et Sagas.Rebus Saga lance IAmInitiatedBy plusieurs fois

Le problème est que la méthode Saga Handle(StartTheSagaMessage message), mettant en œuvre IAmInitiatedBy<StartTheSagaMessage>, est appelée 5 fois et je ne comprends pas pourquoi. De plus, cette méthode publie elle-même un message qui n'est jamais reçu par le bus.

Voici le code de configuration:

var container = new Container(); 

var assemblies = AppDomain.CurrentDomain.GetAssemblies() 
    .Where(i => i.FullName.StartsWith("Messages")); 

container.RegisterCollection(typeof(IHandleMessages<>), assemblies); 

var bus = Configure.With(new SimpleInjectorContainerAdapter(container)) 
    .Logging(l => l.Trace()) 
    .Transport(t => t.UseSqlServer(connectionstring, "Messages", "consumer")) 
    .Routing(r => r.TypeBased().MapAssemblyOf<Job>("consumer")) 
    .Sagas(s => s.StoreInSqlServer(connectionstring, "Sagas", "SagaIndexTable")) 
    .Options(o => 
    { 
     o.SetNumberOfWorkers(1); 
     o.SetMaxParallelism(1); 
    }) 
    .Start(); 

container.Verify(); 

bus.Subscribe<Step1FinishedMessage>().Wait(); 
bus.Subscribe<Step2FinishedMessage>().Wait(); 

var procId = Guid.NewGuid(); 
bus.Send(new StartTheSagaMessage() { ProcessId = procId }); 

Et Code Saga:

public class MySaga : Saga<MySagaData>, 
    IAmInitiatedBy<StartTheSagaMessage>, 
    IHandleMessages<Step1FinishedMessage>, 
    IHandleMessages<Step2FinishedMessage> 
{ 
    public IBus Bus { get; set; } 

    protected override void CorrelateMessages(ICorrelationConfig<MySagaData> config) 
    { 
     config.Correlate<StartTheSagaMessage>(m => m.ProcessId, s => s.SagaProcessId); 
     config.Correlate<Step1FinishedMessage>(m => m.ProcessId, s => s.SagaProcessId); 
     config.Correlate<Step2FinishedMessage>(m => m.ProcessId, s => s.SagaProcessId); 
    } 

    public async Task Handle(StartTheSagaMessage message) 
    { 
     if (IsNew == false) 
      return; 

     Trace.TraceInformation("Mysaga - got StartTheSagaMessage: {0}", message.ProcessId); 
     //The saga is started - Do some stuff - call webservices (in external handler) 
     //When this step is finished the external process replies with a "step1FinishedMessage" 
     this.Data.SagaProcessId = message.ProcessId; 
     //Fake Step1FinishMessage (should be replied from external handler) 
     await Bus.Send(new Step1FinishedMessage() { ProcessId = this.Data.SagaProcessId }); 
    } 

    public async Task Handle(Step1FinishedMessage message) 
    { 
     Trace.TraceInformation("Mysaga - got Step1FinishedMessage: {0}", message.ProcessId); 
     //Sagabehaviour when the Step1 is finished by the external handler 
     this.Data.Step1Finished = true; 
     //After dalying 10 seconds - Send a step2finishedmessage 
     await Bus.Defer(TimeSpan.FromSeconds(10), new Step2FinishedMessage() { ProcessId = this.Data.SagaProcessId }); 
    } 

    public async Task Handle(Step2FinishedMessage message) 
    { 
     await Task.Run(() => 
     //return Task.FromResult<void>(() => 
     { 
      Trace.TraceInformation("Mysaga - got Step2FinishedMessage: {0}", message.ProcessId); 
      //Step2 is handled - finished the saga 
      this.Data.Step2Finished = true; 
      this.MarkAsComplete(); 
     }); 
    } 
} 

L'échantillon complet est basé sur le solution available here.

Qu'est-ce que je fais mal?

Merci pour votre aide.

+0

* solution disponible ici * utilise Autofac? – qujck

+0

Oui, c'est le cas. La solution source utilise également d'anciens paquets nuget. – ilcorvo

+0

Oui, je peux voir, et la mise à jour de tous les paquets produit du code qui ne compile pas. – qujck

Répondre

1

J'ai changé la Saga et ça marche.

Je mets:

private IBus _bus; 

    public MySaga(IBus bus) 
    { 
     _bus = bus; 
    } 

Au lieu de:

public IBus Bus { get; set; } 

Et ça marche! Je ne peux pas comprendre pourquoi, car le débogage Bus n'était pas nul dans la méthode.

+0

Les 5 appels indiquent qu'il doit y avoir eu une erreur. Vous devriez vérifier le journal pour voir ce qui n'allait pas. Si vous vous connectez à la sortie de trace, vous devriez probablement configurer un écouteur de trace qui redirige les logs vers un fichier quelque part - alternativement (et c'est ce que je recommanderais), utilisez l'une des belles bibliothèques de journalisation .NET disponibles, par ex. l'excellent [Serilog] (https://github.com/serilog/serilog) – mookid8000

+0

Malheureusement, il n'y avait pas de message dans le journal. Merci pour la suggestion à propos de Serilog. – ilcorvo