예제 #1
0
        public void CompleteChore()
        {
            IsComplete = true;

            _logger.Log($"Completed { ChoreName }");

            _messageCenter.SendMessage(Owner, $"The chore { ChoreName } is complete.");
        }
예제 #2
0
        public void AnalyzeWorkload(DateTime now, IMessageCenter messageCenter, MessageFactory messageFactory, SiloMessagingOptions options)
        {
            var slowRunningRequestDuration = options.RequestProcessingWarningTime;
            var longQueueTimeDuration      = options.RequestQueueDelayWarningTime;

            List <string> diagnostics = null;

            lock (this)
            {
                if (State != ActivationState.Valid)
                {
                    return;
                }

                if (this.Blocking is object)
                {
                    var message         = this.Blocking;
                    var timeSinceQueued = now - message.QueuedTime;
                    var executionTime   = now - currentRequestStartTime;
                    if (executionTime >= slowRunningRequestDuration)
                    {
                        GetStatusList(ref diagnostics);
                        if (timeSinceQueued.HasValue)
                        {
                            diagnostics.Add($"Message {message} was enqueued {timeSinceQueued} ago and has now been executing for {executionTime}.");
                        }
                        else
                        {
                            diagnostics.Add($"Message {message} has been executing for {executionTime}.");
                        }

                        var response = messageFactory.CreateDiagnosticResponseMessage(message, isExecuting: true, isWaiting: false, diagnostics);
                        messageCenter.SendMessage(response);
                    }
                }

                foreach (var running in RunningRequests)
                {
                    var message   = running.Key;
                    var startTime = running.Value;
                    if (ReferenceEquals(message, this.Blocking))
                    {
                        continue;
                    }

                    // Check how long they've been executing.
                    var executionTime = now - startTime;
                    if (executionTime >= slowRunningRequestDuration)
                    {
                        // Interleaving message X has been executing for a long time
                        GetStatusList(ref diagnostics);
                        var messageDiagnostics = new List <string>(diagnostics)
                        {
                            $"Interleaving message {message} has been executing for {executionTime}."
                        };

                        var response = messageFactory.CreateDiagnosticResponseMessage(message, isExecuting: true, isWaiting: false, messageDiagnostics);
                        messageCenter.SendMessage(response);
                    }
                }

                if (waiting is object)
                {
                    var queueLength = 1;
                    foreach (var message in waiting)
                    {
                        var waitTime = now - message.QueuedTime;
                        if (waitTime >= longQueueTimeDuration)
                        {
                            // Message X has been enqueued on the target grain for Y and is currently position QueueLength in queue for processing.
                            GetStatusList(ref diagnostics);
                            var messageDiagnostics = new List <string>(diagnostics)
                            {
                                $"Message {message} has been enqueued on the target grain for {waitTime} and is currently position {queueLength} in queue for processing."
                            };

                            var response = messageFactory.CreateDiagnosticResponseMessage(message, isExecuting: false, isWaiting: true, messageDiagnostics);
                            messageCenter.SendMessage(response);
                        }

                        queueLength++;
                    }
                }
            }

            void GetStatusList(ref List <string> diagnostics)
            {
                if (diagnostics is object)
                {
                    return;
                }

                diagnostics = new List <string>
                {
                    this.ToDetailedString(),
                    $"TaskScheduler status: {this.WorkItemGroup.DumpStatus()}"
                };
            }
        }
예제 #3
0
        private void ReceiveMessage(Message msg)
        {
            MessagingProcessingStatisticsGroup.OnImaMessageReceived(msg);

            ISchedulingContext context;

            // Find the activation it targets; first check for a system activation, then an app activation
            if (msg.TargetGrain.IsSystemTarget)
            {
                SystemTarget target = directory.FindSystemTarget(msg.TargetActivation);
                if (target == null)
                {
                    MessagingStatisticsGroup.OnRejectedMessage(msg);
                    Message response = this.messageFactory.CreateRejectionResponse(msg, Message.RejectionTypes.Unrecoverable,
                                                                                   String.Format("SystemTarget {0} not active on this silo. Msg={1}", msg.TargetGrain, msg));
                    messageCenter.SendMessage(response);
                    Log.Warn(ErrorCode.MessagingMessageFromUnknownActivation, "Received a message {0} for an unknown SystemTarget: {1}", msg, msg.TargetAddress);
                    return;
                }
                context = target.SchedulingContext;
                switch (msg.Direction)
                {
                case Message.Directions.Request:
                    MessagingProcessingStatisticsGroup.OnImaMessageEnqueued(context);
                    scheduler.QueueWorkItem(new RequestWorkItem(target, msg), context);
                    break;

                case Message.Directions.Response:
                    MessagingProcessingStatisticsGroup.OnImaMessageEnqueued(context);
                    scheduler.QueueWorkItem(new ResponseWorkItem(target, msg), context);
                    break;

                default:
                    Log.Error(ErrorCode.Runtime_Error_100097, "Invalid message: " + msg);
                    break;
                }
            }
            else
            {
                // Run this code on the target activation's context, if it already exists
                ActivationData targetActivation = directory.FindTarget(msg.TargetActivation);
                if (targetActivation != null)
                {
                    lock (targetActivation)
                    {
                        var target = targetActivation; // to avoid a warning about nulling targetActivation under a lock on it
                        if (target.State == ActivationState.Valid)
                        {
                            var overloadException = target.CheckOverloaded(Log);
                            if (overloadException != null)
                            {
                                // Send rejection as soon as we can, to avoid creating additional work for runtime
                                dispatcher.RejectMessage(msg, Message.RejectionTypes.Overloaded, overloadException, "Target activation is overloaded " + target);
                                return;
                            }

                            // Run ReceiveMessage in context of target activation
                            context = new SchedulingContext(target);
                        }
                        else
                        {
                            // Can't use this activation - will queue for another activation
                            target  = null;
                            context = null;
                        }

                        EnqueueReceiveMessage(msg, target, context);
                    }
                }
                else
                {
                    // No usable target activation currently, so run ReceiveMessage in system context
                    EnqueueReceiveMessage(msg, null, null);
                }
            }
        }