2013-11-21 5 views
6

मैं लॉग इन विफल संदेश के लिए एक अच्छा समाधान ढूंढ रहा हूं, त्रुटि कतार के साथ सौदा किए बिना पुनः प्रयास सीमा पार हो जाने के ठीक बाद। मैं अब तक क्या पाया है:masstransit में असफल संदेश लॉग कैसे करें?

  • मैं InMemoryInboundMessageTracker से विरासत और ओवरराइड कर सकते हैं IsRetryLimitExceeded, लेकिन यह मतलब नहीं आईडी को छोड़कर संदेश ही बारे में कोई जानकारी में।
  • मैं IInboundMessageInterceptor लागू कर सकते हैं और पूर्व/PostDispatch में IConsumeContext मिलता है, लेकिन इस बिंदु वहाँ सफलता के बारे में कोई जानकारी नहीं है पर/असफल।

तो एक समाधान के रूप में, मैं में IConsumeContext प्राप्त कर सकते हैं PreDispatch एक कैश के कुछ प्रकार में रख तो यह में एक कैश से बाहर निकलने IsRetryLimitExceeded जब पुन: प्रयास करें सीमा पार हो गई है।

तरीके ऐसे आदेश में कहा जाता है: IsRetryLimitExceeded -> PreDispatch -> PostDispatch

तो मैं एक कैश से सफलतापूर्वक संसाधित संदेश को हटाने के लिए एक अच्छी जगह नहीं मिल रहा।

बेशक मैं प्रतिबंधित आकार के साथ एक कैश का उपयोग कर सकता हूं लेकिन यह पूरा समाधान अजीब लगता है।

इस मामले पर किसी भी विचार की सराहना की जाएगी।

उत्तर

2

आप बस पर अपना संदेश रीट्री ट्रैकिंग लागू और कॉन्फ़िगर कर सकते हैं, ताकि विफल होने वाले संदेश आपके कार्यान्वयन के माध्यम से पारित हो जाएं। आप डिफॉल्ट रीट्री ट्रैकर में प्रतिनिधि हो सकते हैं और केवल ईवेंट को रोक सकते हैं ताकि आप उन पर कार्य कर सकें, या यदि आवश्यक हो तो आप अपनी खुद की पुनः प्रयास ट्रैकिंग लागू कर सकते हैं।

संदेश ट्रैकर फैक्टरी कॉन्फ़िगर करने के लिए प्रतिनिधि है, मुझे लगता है कि इंटरफ़ेस पास है।

+0

हां में है, यह लागू करने/अधिभावी IsRetryLimitExceeded के साथ मामला है। – amstix

+0

यह _IInboundMessageTracker_ इंटरफ़ेस से है। संदेश आईडी के अलावा संदेश और संदर्भ का उपभोग करने के बारे में कोई जानकारी नहीं है, लेकिन कुछ उपयोगी विधियां हैं _MessageWasReceivedSuccessfully_ और _MessageWasMovedToErrorQueue_ जिसका उपयोग कैश से IConsumeContext को निकालने के लिए किया जा सकता है। – amstix

4

मैं इस समाधान के साथ ednded है:

class MessageInterceptor: IInboundMessageInterceptor 
{ 
    public void PreDispatch(IConsumeContext context) 
    { 
     MessageTracker.Register(context); 
    } 

    public void PostDispatch(IConsumeContext context) 
    {} 
} 

class MessageTracker: InMemoryInboundMessageTracker 
{ 
    readonly Logger logger; 

    static readonly ConcurrentDictionary<string, IConsumeContext> DispatchingCache = new ConcurrentDictionary<string, IConsumeContext>(); 

    public MessageTracker(int retryLimit, Logger logger) 
     : base(retryLimit) 
    { 
     this.logger = logger; 
    } 

    public static void Register(IConsumeContext context) 
    { 
     DispatchingCache.GetOrAdd(context.MessageId, context); 
    } 

    public override void MessageWasReceivedSuccessfully(string id) 
    { 
     base.MessageWasReceivedSuccessfully(id); 

     IConsumeContext value; 
     DispatchingCache.TryRemove(id, out value); 
    } 

    public override bool IsRetryLimitExceeded(string id, out Exception retryException, out IEnumerable<Action> faultActions) 
    { 
     var result = base.IsRetryLimitExceeded(id, out retryException, out faultActions); 

     IConsumeContext failed; 
     if (!result || !DispatchingCache.TryRemove(id, out failed)) 
      return result; 

     // --> log failed IConsumeContext with exception 

     return true; 
    } 
} 

और उन वर्गों प्लग करने के लिए

 serviceBus = ServiceBusFactory.New(config => 
     { 
      ... 
      config.AddBusConfigurator(new PostCreateBusBuilderConfigurator(sb => 
      { 
       var interceptorConfig = new InboundMessageInterceptorConfigurator(sb.InboundPipeline); 
       interceptorConfig.Create(new MessageInterceptor()); 
      })); 

      config.SetDefaultInboundMessageTrackerFactory(retryLimit => new MessageTracker(retryLimit, LogManager.GetCurrentClassLogger())); 
     }); 
संबंधित मुद्दे