Beispiel #1
0
        /// <summary>
        /// Enqueue message for local handling after transaction completes
        /// </summary>
        /// <param name="message"></param>
        /// <param name="targetActivation"></param>
        private void EnqueueRequest(Message message, ActivationData targetActivation)
        {
            var overloadException = targetActivation.CheckOverloaded(logger);

            if (overloadException != null)
            {
                MessagingProcessingStatisticsGroup.OnDispatcherMessageProcessedError(message, "Overload2");
                RejectMessage(message, Message.RejectionTypes.Overloaded, overloadException, "Target activation is overloaded " + targetActivation);
                return;
            }
            if (Message.WriteMessagingTraces)
            {
                message.AddTimestamp(Message.LifecycleTag.EnqueueWaiting);
            }

            bool enqueuedOk = targetActivation.EnqueueMessage(message);

            if (!enqueuedOk)
            {
                ProcessRequestToInvalidActivation(message, targetActivation.Address, targetActivation.ForwardingAddress, "EnqueueRequest");
            }

            // Dont count this as end of processing. The message will come back after queueing via HandleIncomingRequest.

#if DEBUG
            // This is a hot code path, so using #if to remove diags from Release version
            // Note: Caller already holds lock on activation
            if (logger.IsVerbose2)
            {
                logger.Verbose2(ErrorCode.Dispatcher_EnqueueMessage,
                                "EnqueueMessage for {0}: targetActivation={1}", message.TargetActivation, targetActivation.DumpStatus());
            }
#endif
        }
Beispiel #2
0
        internal void IncrementGrainCounter(string grainTypeName)
        {
            if (logger.IsVerbose2)
            {
                logger.Verbose2("Increment Grain Counter {0}", grainTypeName);
            }
            CounterStatistic ctr = FindGrainCounter(grainTypeName);

            ctr.Increment();
        }
        public static Assembly OnReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
        {
            // loading into the reflection-only context doesn't resolve dependencies automatically.
            // we're faced with the choice of ignoring arguably false dependency-missing exceptions or
            // loading the dependent assemblies into the reflection-only context.
            //
            // i opted to load dependencies (by implementing OnReflectionOnlyAssemblyResolve)
            // because it's an opportunity to quickly identify assemblies that wouldn't load under
            // normal circumstances.

            try
            {
                var name = AppDomain.CurrentDomain.ApplyPolicy(args.Name);
                return(Assembly.ReflectionOnlyLoad(name));
            }
            catch (IOException)
            {
                if (logger.IsVerbose2)
                {
                    logger.Verbose2(FormatReflectionOnlyAssemblyResolveFailureMessage(sender, args));
                }

                var dirName      = Path.GetDirectoryName(args.RequestingAssembly.Location);
                var assemblyName = new AssemblyName(args.Name);
                var fileName     = string.Format("{0}.dll", assemblyName.Name);
                var pathName     = Path.Combine(dirName, fileName);
                if (logger.IsVerbose2)
                {
                    logger.Verbose2("failed to find assembly {0} in {1}; searching for {2} instead.",
                                    assemblyName.FullName, dirName, pathName);
                }

                try
                {
                    return(Assembly.ReflectionOnlyLoadFrom(pathName));
                }
                catch (FileNotFoundException)
                {
                    if (logger.IsVerbose2)
                    {
                        logger.Verbose(FormatReflectionOnlyAssemblyResolveFailureMessage(sender, args));
                    }
                    throw;
                }
            }
        }
Beispiel #4
0
 internal void DropExpiredMessage(MessagingStatisticsGroup.Phase phase)
 {
     MessagingStatisticsGroup.OnMessageExpired(phase);
     if (logger.IsVerbose2)
     {
         logger.Verbose2("Dropping an expired message: {0}", this);
     }
     ReleaseBodyAndHeaderBuffers();
 }
Beispiel #5
0
        public void DoCallback(Message response)
        {
            if (alreadyFired)
            {
                return;
            }
            lock (this)
            {
                if (alreadyFired)
                {
                    return;
                }

                if (response.Result == Message.ResponseTypes.Rejection && response.RejectionType == Message.RejectionTypes.Transient)
                {
                    if (resendFunc(Message))
                    {
                        return;
                    }
                }

                alreadyFired = true;
                DisposeTimer();
                if (StatisticsCollector.CollectApplicationRequestsStats)
                {
                    timeSinceIssued.Stop();
                }
                if (unregister != null)
                {
                    unregister();
                }
            }
            if (Message.WriteMessagingTraces)
            {
                response.AddTimestamp(Message.LifecycleTag.InvokeIncoming);
            }
            if (logger.IsVerbose2)
            {
                logger.Verbose2("Message {0} timestamps: {1}", response, response.GetTimestampString());
            }
            if (StatisticsCollector.CollectApplicationRequestsStats)
            {
                ApplicationRequestsStatisticsGroup.OnAppRequestsEnd(timeSinceIssued.Elapsed);
            }
            // do callback outside the CallbackData lock. Just not a good practice to hold a lock for this unrelated operation.
            callback(response, context);
        }
        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);
                }
            }
        }
Beispiel #7
0
        public void AddTimestamp(LifecycleTag tag)
        {
            if (logger.IsVerbose2)
            {
                if (LogVerbose(tag))
                {
                    logger.Verbose("Message {0} {1}", tag, this);
                }
                else if (logger.IsVerbose2)
                {
                    logger.Verbose2("Message {0} {1}", tag, this);
                }
            }

            if (WriteMessagingTraces)
            {
                var now       = DateTime.UtcNow;
                var timestamp = new List <object> {
                    tag, now
                };

                object        val;
                List <object> list = null;
                if (headers.TryGetValue(Header.TIMESTAMPS, out val))
                {
                    list = val as List <object>;
                }
                if (list == null)
                {
                    list = new List <object>();
                    lock (headers)
                    {
                        headers[Header.TIMESTAMPS] = list;
                    }
                }
                else if (list.Count > 0)
                {
                    var last = list[list.Count - 1] as List <object>;
                    if (last != null)
                    {
                        var context = DebugContext;
                        if (String.IsNullOrEmpty(context))
                        {
                            context = "Unspecified";
                        }
                        TransitionStats[,] entry;
                        bool found;
                        lock (lifecycleStatistics)
                        {
                            found = lifecycleStatistics.TryGetValue(context, out entry);
                        }
                        if (!found)
                        {
                            var newEntry = new TransitionStats[32, 32];
                            for (int i = 0; i < 32; i++)
                            {
                                for (int j = 0; j < 32; j++)
                                {
                                    newEntry[i, j] = new TransitionStats();
                                }
                            }
                            lock (lifecycleStatistics)
                            {
                                if (!lifecycleStatistics.TryGetValue(context, out entry))
                                {
                                    entry = newEntry;
                                    lifecycleStatistics.Add(context, entry);
                                }
                            }
                        }
                        int from = (int)(LifecycleTag)(last[0]);
                        int to   = (int)tag;
                        entry[from, to].RecordTransition(now.Subtract((DateTime)last[1]));
                    }
                }
                list.Add(timestamp);
            }
            if (OnTrace != null)
            {
                OnTrace(this, tag);
            }
        }