internal static void OnRejectedMessage(Message msg) { if (msg == null || !msg.ContainsHeader(Message.Header.DIRECTION)) return; int direction = (int)msg.Direction; if (RejectedMessages[direction] == null) { RejectedMessages[direction] = CounterStatistic.FindOrCreate( new StatisticName(StatisticNames.MESSAGING_REJECTED_PER_DIRECTION, Enum.GetName(typeof(Message.Directions), direction))); } RejectedMessages[direction].Increment(); }
public void ReceiveResponse(Message message) { if (message.Result == Message.ResponseTypes.Rejection) { if (!message.TargetSilo.Matches(this.CurrentSilo)) { // gatewayed message - gateway back to sender if (logger.IsVerbose2) { logger.Verbose2(ErrorCode.Dispatcher_NoCallbackForRejectionResp, "No callback for rejection response message: {0}", message); } dispatcher.Transport.SendMessage(message); return; } if (logger.IsVerbose) { logger.Verbose(ErrorCode.Dispatcher_HandleMsg, "HandleMessage {0}", message); } switch (message.RejectionType) { case Message.RejectionTypes.DuplicateRequest: // try to remove from callbackData, just in case it is still there. break; case Message.RejectionTypes.Overloaded: break; case Message.RejectionTypes.Unrecoverable: // fall through & reroute case Message.RejectionTypes.Transient: if (!message.ContainsHeader(Message.Header.CACHE_INVALIDATION_HEADER)) { // Remove from local directory cache. Note that SendingGrain is the original target, since message is the rejection response. // If CacheMgmtHeader is present, we already did this. Otherwise, we left this code for backward compatability. // It should be retired as we move to use CacheMgmtHeader in all relevant places. directory.InvalidateCacheEntry(message.SendingAddress); } break; default: logger.Error(ErrorCode.Dispatcher_InvalidEnum_RejectionType, "Missing enum in switch: " + message.RejectionType); break; } } CallbackData callbackData; bool found = callbacks.TryGetValue(message.Id, out callbackData); if (found) { // IMPORTANT: we do not schedule the response callback via the scheduler, since the only thing it does // is to resolve/break the resolver. The continuations/waits that are based on this resolution will be scheduled as work items. callbackData.DoCallback(message); } else { if (logger.IsVerbose) { logger.Verbose(ErrorCode.Dispatcher_NoCallbackForResp, "No callback for response message: " + message); } } }