2013-02-25 4 views
6

Nella mia applicazione di test posso vedere i messaggi che sono stati elaborati con un'eccezione che viene automaticamente inserita nell'EasyNetQ_Default_Error_Queue predefinito, che è ottima. Posso quindi eseguire correttamente il dump o l'accodamento di questi messaggi utilizzando Hosepipe, che funziona anche bene, ma richiede il passaggio alla riga di comando e la chiamata sia a Hosepipe che all'API RabbitMQ per eliminare la coda dei messaggi riprovati.C'è un modo semplice per iscriversi alla coda degli errori di default in EasyNetQ?

così sto pensando l'approccio più semplice per la mia domanda è quello di iscriversi semplicemente alla coda di errore, così posso ri-processo utilizzando la stessa infrastruttura. Ma in EastNetQ, la coda di errore sembra essere speciale. Abbiamo bisogno di iscriversi utilizzando un tipo corretto e instradamento ID, quindi non sono sicuro di cosa questi valori dovrebbero essere per la coda di errore:

bus.Subscribe<WhatShouldThisBe>("and-this", ReprocessErrorMessage);

Posso usare il semplice API per iscriversi alla coda di errore, o devo scavare nel advanced API?

Se il tipo del mio messaggio originale era TestMessage, quindi mi piacerebbe essere in grado di fare qualcosa del genere:

bus.Subscribe<ErrorMessage<TestMessage>>("???", ReprocessErrorMessage);

dove ErrorMessage è una classe fornita da EasyNetQ per avvolgere tutti gli errori. È possibile?

risposta

3

Non è possibile utilizzare il semplice API per iscriversi alla coda di errore perché non segue EasyNetQ tipo di coda convenzioni di denominazione - forse questo è qualcosa che dovrebbe essere risolto;)

Ma l'API avanzata funziona bene. Non riceverai il messaggio originale, ma è facile ottenere la rappresentazione JSON che potresti declassare da te abbastanza facilmente (usando Newtonsoft.JSON). Ecco un esempio di ciò che il codice di abbonamento dovrebbe essere simile:

[Test] 
[Explicit("Requires a RabbitMQ server on localhost")] 
public void Should_be_able_to_subscribe_to_error_messages() 
{ 
    var errorQueueName = new Conventions().ErrorQueueNamingConvention(); 
    var queue = Queue.DeclareDurable(errorQueueName); 
    var autoResetEvent = new AutoResetEvent(false); 

    bus.Advanced.Subscribe<SystemMessages.Error>(queue, (message, info) => 
    { 
     var error = message.Body; 

     Console.Out.WriteLine("error.DateTime = {0}", error.DateTime); 
     Console.Out.WriteLine("error.Exception = {0}", error.Exception); 
     Console.Out.WriteLine("error.Message = {0}", error.Message); 
     Console.Out.WriteLine("error.RoutingKey = {0}", error.RoutingKey); 

     autoResetEvent.Set(); 
     return Task.Factory.StartNew(() => { }); 
    }); 

    autoResetEvent.WaitOne(1000); 
} 

ho dovuto correggere un piccolo bug nel messaggio di errore la scrittura di codice in EasyNetQ prima di questo ha funzionato, quindi si prega di ottenere una versione> = 0.9.2.73 prima di provare fuori. Si può vedere il codice di esempio here

+0

Grazie per il vostro aiuto Mike. Pensi che sarebbe una buona idea esporre un involucro amichevole per questo? Per impostazione predefinita, la semplice API scrive in questa coda di errore, quindi per me ha senso avere un meccanismo per consumare in modo trasparente anche questi errori. Anche con il tuo codice qui sopra, penso di aver bisogno di avere qualche tipo di istruzione switch nel gestore dei messaggi di errore ('switch (error.BasicProperties.Type)'), che poi mi permetterà di deserializzare il messaggio originale nel tipo corretto, che è un po 'brutto. Sarebbe bello se potessi iscrivermi al tipo specifico di errore a cui sono interessato. –

+0

BTW Adoro la libreria EastNetQ. Grazie per il tuo duro lavoro e l'ottima documentazione. –

+0

Grazie per le belle parole! Ho aggiunto il tuo suggerimento alla lista dei problemi https://github.com/mikehadlow/EasyNetQ/issues/71 ma non ne sono completamente convinto. –

0

codice che funziona: (ho preso una supposizione)

La screwyness con il 'foo' è perché se mi limito a passare che la funzione HandleErrorMessage2 nel consumare lo chiamano, si può' t capire che restituisce un vuoto e non un compito, quindi non è possibile capire quale sovraccarico usare. (VS 2012) Assegnare a una variabile lo rende felice. Si desidera rilevare il valore restituito della chiamata per poter annullare l'iscrizione smaltendo l'oggetto.

Si noti inoltre che qualcuno ha utilizzato un nome oggetto di sistema (coda) invece di renderlo un EasyNetQueue o qualcosa del genere, quindi è necessario aggiungere il chiarimento usando per il compilatore o specificarlo completamente.

using Queue = EasyNetQ.Topology.Queue; 

    private const string QueueName = "EasyNetQ_Default_Error_Queue"; 
    public static void Should_be_able_to_subscribe_to_error_messages(IBus bus) 
    { 
    Action <IMessage<Error>, MessageReceivedInfo> foo = HandleErrorMessage2; 

    IQueue queue = new Queue(QueueName,false); 
    bus.Advanced.Consume<Error>(queue, foo); 
    } 

    private static void HandleErrorMessage2(IMessage<Error> msg, MessageReceivedInfo info) 
{ 
} 
Problemi correlati