Example #1
0
 public static PlacementResult IdentifySelection(ActivationAddress address)
 {
     return
         new PlacementResult
             {
                 Activation = address.Activation,
                 Silo = address.Silo
             };
 }
Example #2
0
        internal void ProcessRequestsToInvalidActivation(
            List<Message> messages,
            ActivationAddress oldAddress,
            ActivationAddress forwardingAddress, 
            string failedOperation,
            Exception exc = null)
        {
            // Just use this opportunity to invalidate local Cache Entry as well. 
            if (oldAddress != null)
            {
                Silo.CurrentSilo.LocalGrainDirectory.InvalidateCacheEntry(oldAddress);
            }
            logger.Info(ErrorCode.Messaging_Dispatcher_ForwardingRequests, 
                String.Format("Forwarding {0} requests to old address {1} after {2}.", messages.Count, oldAddress, failedOperation));

            // IMPORTANT: do not do anything on activation context anymore, since this activation is invalid already.
            Scheduler.QueueWorkItem(new ClosureWorkItem(
                () =>
                {
                    foreach (var message in messages)
                    {
                        TryForwardRequest(message, oldAddress, forwardingAddress, failedOperation, exc);
                    }
                }
                ), catalog.SchedulingContext);
        }
Example #3
0
        private void RerouteAllQueuedMessages(ActivationData activation, ActivationAddress forwardingAddress, string failedOperation, Exception exc = null)
        {
            lock (activation)
            {
                List<Message> msgs = activation.DequeueAllWaitingMessages();
                if (msgs == null || msgs.Count <= 0) return;

                if (logger.IsVerbose) logger.Verbose(ErrorCode.Catalog_RerouteAllQueuedMessages, String.Format("RerouteAllQueuedMessages: {0} msgs from Invalid activation {1}.", msgs.Count(), activation));
                dispatcher.ProcessRequestsToInvalidActivation(msgs, activation.Address, forwardingAddress, failedOperation, exc);
            }
        }
Example #4
0
        private async Task RegisterActivationInGrainDirectory(ActivationAddress address, bool singleActivationMode)
        {
            if (singleActivationMode)
            {
                ActivationAddress returnedAddress = await scheduler.RunOrQueueTask(() => directory.RegisterSingleActivationAsync(address), this.SchedulingContext);
                if (address.Equals(returnedAddress)) return;
                
                SiloAddress primaryDirectoryForGrain = directory.GetPrimaryForGrain(address.Grain);
                var dae = new DuplicateActivationException
                {
                    ActivationToUse = returnedAddress,
                    PrimaryDirectoryForGrain = primaryDirectoryForGrain
                };

                throw dae;
            }
            
            await scheduler.RunOrQueueTask(() => directory.RegisterAsync(address), this.SchedulingContext);
        }
Example #5
0
 public DuplicateActivationException(ActivationAddress activationToUse, SiloAddress primaryDirectoryForGrain)
     : base("DuplicateActivationException")
 {
     ActivationToUse = activationToUse;
     PrimaryDirectoryForGrain = primaryDirectoryForGrain;
 }
Example #6
0
 public NonExistentActivationException(string msg, ActivationAddress nonExistentActivation, bool isStatelessWorker)
     : base(msg)
 {
     NonExistentActivation = nonExistentActivation;
     IsStatelessWorker = isStatelessWorker;
 }
Example #7
0
        internal void AddToCacheInvalidationHeader(ActivationAddress address)
        {
            var list = new List<ActivationAddress>();
            if (CacheInvalidationHeader != null)
            {
                list.AddRange(CacheInvalidationHeader);
            }

            list.Add(address);
            CacheInvalidationHeader = list;
        }
 public IGrainContext CreateContext(ActivationAddress address) => new StatelessWorkerGrainContext(address, _sharedContext, _innerActivator);
Example #9
0
        internal void TryForwardRequest(Message message, ActivationAddress oldAddress, ActivationAddress forwardingAddress, string failedOperation, Exception exc = null)
        {
            bool forwardingSucceded = true;

            try
            {
                logger.Info(ErrorCode.Messaging_Dispatcher_TryForward,
                            String.Format("Trying to forward after {0}, ForwardCount = {1}. Message {2}.", failedOperation, message.ForwardCount, message));

                MessagingProcessingStatisticsGroup.OnDispatcherMessageReRouted(message);
                if (oldAddress != null)
                {
                    message.AddToCacheInvalidationHeader(oldAddress);
                }
                forwardingSucceded = InsideRuntimeClient.Current.TryForwardMessage(message, forwardingAddress);
            }
            catch (Exception exc2)
            {
                forwardingSucceded = false;
                exc = exc2;
            }
            finally
            {
                if (!forwardingSucceded)
                {
                    var str = String.Format("Forwarding failed: tried to forward message {0} for {1} times after {2} to invalid activation. Rejecting now.",
                                            message, message.ForwardCount, failedOperation);
                    logger.Warn(ErrorCode.Messaging_Dispatcher_TryForwardFailed, str, exc);
                    RejectMessage(message, Message.RejectionTypes.Transient, exc, str);
                }
            }
        }
Example #10
0
        internal void TryForwardRequest(Message message, ActivationAddress oldAddress, ActivationAddress forwardingAddress, string failedOperation, Exception exc = null)
        {
            bool forwardingSucceded = true;

            try
            {
                this.messagingTrace.OnDispatcherForwarding(message, oldAddress, forwardingAddress, failedOperation, exc);

                // if this message is from a different cluster and hit a non-existing activation
                // in this cluster (which can happen due to stale cache or directory states)
                // we forward it back to the original silo it came from in the original cluster,
                // and target it to a fictional activation that is guaranteed to not exist.
                // This ensures that the GSI protocol creates a new instance there instead of here.
                if (forwardingAddress == null &&
                    message.TargetSilo != message.SendingSilo &&
                    !this.localGrainDirectory.IsSiloInCluster(message.SendingSilo))
                {
                    message.IsReturnedFromRemoteCluster = true; // marks message to force invalidation of stale directory entry
                    forwardingAddress = ActivationAddress.NewActivationAddress(message.SendingSilo, message.TargetGrain);
                    logger.Info(ErrorCode.Messaging_Dispatcher_ReturnToOriginCluster, $"Forwarding back to origin cluster, to fictional activation {message}");
                }

                if (oldAddress != null)
                {
                    message.AddToCacheInvalidationHeader(oldAddress);
                }

                forwardingSucceded = this.TryForwardMessage(message, forwardingAddress);
            }
            catch (Exception exc2)
            {
                forwardingSucceded = false;
                exc = exc2;
            }
            finally
            {
                var sentRejection = false;

                // If the message was a one-way message, send a cache invalidation response even if the message was successfully forwarded.
                if (message.Direction == Message.Directions.OneWay)
                {
                    this.RejectMessage(
                        message,
                        Message.RejectionTypes.CacheInvalidation,
                        exc,
                        "OneWay message sent to invalid activation");
                    sentRejection = true;
                }

                if (!forwardingSucceded)
                {
                    this.messagingTrace.OnDispatcherForwardingFailed(message, oldAddress, forwardingAddress, failedOperation, exc);
                    if (!sentRejection)
                    {
                        var str = $"Forwarding failed: tried to forward message {message} for {message.ForwardCount} times after {failedOperation} to invalid activation. Rejecting now.";
                        RejectMessage(message, Message.RejectionTypes.Transient, exc, str);
                    }
                }
            }
        }
 public bool Matches(ActivationAddress other)
 {
     return(Equals(Grain, other.Grain) && Equals(Activation, other.Activation));
 }
Example #12
0
        private void ResendMessageImpl(Message message, ActivationAddress forwardingAddress = null)
        {
            if (logger.IsVerbose) logger.Verbose("Resend {0}", message);
            message.TargetHistory = message.GetTargetHistory();

            if (message.TargetGrain.IsSystemTarget)
            {
                dispatcher.SendSystemTargetMessage(message);
            }
            else if (forwardingAddress != null)
            {
                message.TargetAddress = forwardingAddress;
                message.IsNewPlacement = false;
                dispatcher.Transport.SendMessage(message);
            }
            else
            {
                message.TargetActivation = null;
                message.TargetSilo = null;
                message.ClearTargetAddress();
                dispatcher.SendMessage(message);
            }
        }
Example #13
0
        /// <summary>
        /// Receive a new message:
        /// - validate order constraints, queue (or possibly redirect) if out of order
        /// - validate transactions constraints
        /// - invoke handler if ready, otherwise enqueue for later invocation
        /// </summary>
        /// <param name="message"></param>
        public void ReceiveMessage(Message message)
        {
            MessagingProcessingStatisticsGroup.OnDispatcherMessageReceive(message);
            // Don't process messages that have already timed out
            if (message.IsExpired)
            {
                logger.Warn(ErrorCode.Dispatcher_DroppingExpiredMessage, "Dropping an expired message: {0}", message);
                MessagingProcessingStatisticsGroup.OnDispatcherMessageProcessedError(message, "Expired");
                message.DropExpiredMessage(MessagingStatisticsGroup.Phase.Dispatch);
                return;
            }

            // check if its targeted at a new activation
            if (message.TargetGrain.IsSystemTarget)
            {
                MessagingProcessingStatisticsGroup.OnDispatcherMessageProcessedError(message, "ReceiveMessage on system target.");
                throw new InvalidOperationException("Dispatcher was called ReceiveMessage on system target for " + message);
            }

            if (errorInjection && ShouldInjectError(message))
            {
                if (logger.IsVerbose)
                {
                    logger.Verbose(ErrorCode.Dispatcher_InjectingRejection, "Injecting a rejection");
                }
                MessagingProcessingStatisticsGroup.OnDispatcherMessageProcessedError(message, "ErrorInjection");
                RejectMessage(message, Message.RejectionTypes.Unrecoverable, null, "Injected rejection");
                return;
            }

            try
            {
                Task           ignore;
                ActivationData target = catalog.GetOrCreateActivation(
                    message.TargetAddress,
                    message.IsNewPlacement,
                    message.NewGrainType,
                    message.GenericGrainType,
                    out ignore);

                if (ignore != null)
                {
                    ignore.Ignore();
                }

                if (message.Direction == Message.Directions.Response)
                {
                    ReceiveResponse(message, target);
                }
                else // Request or OneWay
                {
                    if (SiloCanAcceptRequest(message))
                    {
                        ReceiveRequest(message, target);
                    }
                    else if (message.MayResend(config.Globals))
                    {
                        // Record that this message is no longer flowing through the system
                        MessagingProcessingStatisticsGroup.OnDispatcherMessageProcessedError(message, "Redirecting");
                        throw new NotImplementedException("RedirectRequest() is believed to be no longer necessary; please contact the Orleans team if you see this error.");
                    }
                    else
                    {
                        // Record that this message is no longer flowing through the system
                        MessagingProcessingStatisticsGroup.OnDispatcherMessageProcessedError(message, "Rejecting");
                        RejectMessage(message, Message.RejectionTypes.Transient, null, "Shutting down");
                    }
                }
            }
            catch (Exception ex)
            {
                try
                {
                    MessagingProcessingStatisticsGroup.OnDispatcherMessageProcessedError(message, "Non-existent activation");

                    var nea = ex as Catalog.NonExistentActivationException;
                    if (nea == null)
                    {
                        var str = String.Format("Error creating activation for {0}. Message {1}", message.NewGrainType, message);
                        logger.Error(ErrorCode.Dispatcher_ErrorCreatingActivation, str, ex);
                        throw new OrleansException(str, ex);
                    }

                    logger.Warn(ErrorCode.Dispatcher_Intermediate_GetOrCreateActivation,
                                String.Format("Intermediate warning for NonExistentActivation from Catalog.GetOrCreateActivation for message {0}", message), ex);

                    ActivationAddress nonExistentActivation = nea.NonExistentActivation;

                    if (message.Direction != Message.Directions.Response)
                    {
                        // Un-register the target activation so we don't keep getting spurious messages.
                        // The time delay (one minute, as of this writing) is to handle the unlikely but possible race where
                        // this request snuck ahead of another request, with new placement requested, for the same activation.
                        // If the activation registration request from the new placement somehow sneaks ahead of this un-registration,
                        // we want to make sure that we don't un-register the activation we just created.
                        // We would add a counter here, except that there's already a counter for this in the Catalog.
                        // Note that this has to run in a non-null scheduler context, so we always queue it to the catalog's context
                        if (config.Globals.DirectoryLazyDeregistrationDelay > TimeSpan.Zero)
                        {
                            Scheduler.QueueWorkItem(new ClosureWorkItem(
                                                        // don't use message.TargetAddress, cause it may have been removed from the headers by this time!
                                                        async() =>
                            {
                                try
                                {
                                    await Silo.CurrentSilo.LocalGrainDirectory.UnregisterConditionallyAsync(
                                        nonExistentActivation);
                                }
                                catch (Exception exc)
                                {
                                    logger.Warn(ErrorCode.Dispatcher_FailedToUnregisterNonExistingAct,
                                                String.Format("Failed to un-register NonExistentActivation {0}",
                                                              nonExistentActivation), exc);
                                }
                            },
                                                        () => "LocalGrainDirectory.UnregisterConditionallyAsync"),
                                                    catalog.SchedulingContext);
                        }
                        ProcessRequestToInvalidActivation(message, nonExistentActivation, null, "Non-existent activation");
                    }
                    else
                    {
                        logger.Warn(ErrorCode.Dispatcher_NoTargetActivation,
                                    "No target activation {0} for response message: {1}", nonExistentActivation, message);
                        Silo.CurrentSilo.LocalGrainDirectory.InvalidateCacheEntry(nonExistentActivation);
                    }
                }
                catch (Exception exc)
                {
                    // Unable to create activation for this request - reject message
                    RejectMessage(message, Message.RejectionTypes.Transient, exc);
                }
            }
        }
Example #14
0
 public ActivationAddress ToAddress(GrainId grainId)
 {
     return(ActivationAddress.GetAddress(Silo, grainId, Activation));
 }
Example #15
0
        public ActivationData(ActivationAddress addr, string genericArguments, PlacementStrategy placedUsing, MultiClusterRegistrationStrategy registrationStrategy, IActivationCollector collector, TimeSpan ageLimit)
        {
            if (null == addr) throw new ArgumentNullException("addr");
            if (null == placedUsing) throw new ArgumentNullException("placedUsing");
            if (null == collector) throw new ArgumentNullException("collector");

            logger = LogManager.GetLogger("ActivationData", LoggerType.Runtime);
            ResetKeepAliveRequest();
            Address = addr;
            State = ActivationState.Create;
            PlacedUsing = placedUsing;
            RegistrationStrategy = registrationStrategy;
            if (!Grain.IsSystemTarget && !Constants.IsSystemGrain(Grain))
            {
                this.collector = collector;
            }
            CollectionAgeLimit = ageLimit;

            GrainReference = GrainReference.FromGrainId(addr.Grain, genericArguments,
                Grain.IsSystemTarget ? addr.Silo : null);
        }
Example #16
0
        internal bool TryForwardMessage(Message message, ActivationAddress forwardingAddress)
        {
            if (!message.MayForward(Config.Globals)) return false;

            message.ForwardCount = message.ForwardCount + 1;
            MessagingProcessingStatisticsGroup.OnIgcMessageForwared(message);
            ResendMessageImpl(message, forwardingAddress);
            return true;
        }
Example #17
0
        internal void TryForwardRequest(Message message, ActivationAddress oldAddress, ActivationAddress forwardingAddress, string failedOperation, Exception exc = null)
        {
            bool forwardingSucceded = true;

            try
            {
                logger.Info(ErrorCode.Messaging_Dispatcher_TryForward,
                            String.Format("Trying to forward after {0}, ForwardCount = {1}. Message {2}.", failedOperation, message.ForwardCount, message));

                // if this message is from a different cluster and hit a non-existing activation
                // in this cluster (which can happen due to stale cache or directory states)
                // we forward it back to the original silo it came from in the original cluster,
                // and target it to a fictional activation that is guaranteed to not exist.
                // This ensures that the GSI protocol creates a new instance there instead of here.
                if (forwardingAddress == null &&
                    message.TargetSilo != message.SendingSilo &&
                    !this.localGrainDirectory.IsSiloInCluster(message.SendingSilo))
                {
                    message.IsReturnedFromRemoteCluster = true; // marks message to force invalidation of stale directory entry
                    forwardingAddress = ActivationAddress.NewActivationAddress(message.SendingSilo, message.TargetGrain);
                    logger.Info(ErrorCode.Messaging_Dispatcher_ReturnToOriginCluster,
                                String.Format("Forwarding back to origin cluster, to fictional activation {0}", message));
                }

                MessagingProcessingStatisticsGroup.OnDispatcherMessageReRouted(message);
                if (oldAddress != null)
                {
                    message.AddToCacheInvalidationHeader(oldAddress);
                }

                forwardingSucceded = this.TryForwardMessage(message, forwardingAddress);
            }
            catch (Exception exc2)
            {
                forwardingSucceded = false;
                exc = exc2;
            }
            finally
            {
                if (!forwardingSucceded)
                {
                    var str = String.Format("Forwarding failed: tried to forward message {0} for {1} times after {2} to invalid activation. Rejecting now.",
                                            message, message.ForwardCount, failedOperation);
                    logger.Warn(ErrorCode.Messaging_Dispatcher_TryForwardFailed, str, exc);
                    RejectMessage(message, Message.RejectionTypes.Transient, exc, str);
                }
            }
        }
Example #18
0
        internal void TryForwardRequest(Message message, ActivationAddress oldAddress, ActivationAddress forwardingAddress, string failedOperation, Exception exc = null)
        {
            bool forwardingSucceded = true;
            try
            {

                logger.Info(ErrorCode.Messaging_Dispatcher_TryForward, 
                    String.Format("Trying to forward after {0}, ForwardCount = {1}. Message {2}.", failedOperation, message.ForwardCount, message));

                // if this message is from a different cluster and hit a non-existing activation
                // in this cluster (which can happen due to stale cache or directory states)
                // we forward it back to the original silo it came from in the original cluster,
                // and target it to a fictional activation that is guaranteed to not exist.
                // This ensures that the GSI protocol creates a new instance there instead of here.
                if (forwardingAddress == null
                    && message.TargetSilo != message.SendingSilo
                    && !Silo.CurrentSilo.LocalGrainDirectory.IsSiloInCluster(message.SendingSilo))
                {
                    message.IsReturnedFromRemoteCluster = true; // marks message to force invalidation of stale directory entry
                    forwardingAddress = ActivationAddress.NewActivationAddress(message.SendingSilo, message.TargetGrain);
                    logger.Info(ErrorCode.Messaging_Dispatcher_ReturnToOriginCluster,
                        String.Format("Forwarding back to origin cluster, to fictional activation {0}", message));
                }

                MessagingProcessingStatisticsGroup.OnDispatcherMessageReRouted(message);
                if (oldAddress != null)
                {
                    message.AddToCacheInvalidationHeader(oldAddress);
                }

                forwardingSucceded = InsideRuntimeClient.Current.TryForwardMessage(message, forwardingAddress);
            }
            catch (Exception exc2)
            {
                forwardingSucceded = false;
                exc = exc2;
            }
            finally
            {
                if (!forwardingSucceded)
                {
                    var str = String.Format("Forwarding failed: tried to forward message {0} for {1} times after {2} to invalid activation. Rejecting now.", 
                        message, message.ForwardCount, failedOperation);
                    logger.Warn(ErrorCode.Messaging_Dispatcher_TryForwardFailed, str, exc);
                    RejectMessage(message, Message.RejectionTypes.Transient, exc, str);
                }
            }
        }
Example #19
0
        /// <summary>
        /// Receive a new message:
        /// - validate order constraints, queue (or possibly redirect) if out of order
        /// - validate transactions constraints
        /// - invoke handler if ready, otherwise enqueue for later invocation
        /// </summary>
        /// <param name="message"></param>
        public void ReceiveMessage(Message message)
        {
            MessagingProcessingStatisticsGroup.OnDispatcherMessageReceive(message);
            // Don't process messages that have already timed out
            if (message.IsExpired)
            {
                logger.Warn(ErrorCode.Dispatcher_DroppingExpiredMessage, "Dropping an expired message: {0}", message);
                MessagingProcessingStatisticsGroup.OnDispatcherMessageProcessedError(message, "Expired");
                message.DropExpiredMessage(MessagingStatisticsGroup.Phase.Dispatch);
                return;
            }

            // check if its targeted at a new activation
            if (message.TargetGrain.IsSystemTarget)
            {
                MessagingProcessingStatisticsGroup.OnDispatcherMessageProcessedError(message, "ReceiveMessage on system target.");
                throw new InvalidOperationException("Dispatcher was called ReceiveMessage on system target for " + message);
            }

            try
            {
                Task           ignore;
                ActivationData target = catalog.GetOrCreateActivation(
                    message.TargetAddress,
                    message.IsNewPlacement,
                    message.NewGrainType,
                    String.IsNullOrEmpty(message.GenericGrainType) ? null : message.GenericGrainType,
                    message.RequestContextData,
                    out ignore);

                if (ignore != null)
                {
                    ignore.Ignore();
                }

                if (message.Direction == Message.Directions.Response)
                {
                    ReceiveResponse(message, target);
                }
                else // Request or OneWay
                {
                    if (target.State == ActivationState.Valid)
                    {
                        this.activationCollector.TryRescheduleCollection(target);
                    }
                    // Silo is always capable to accept a new request. It's up to the activation to handle its internal state.
                    // If activation is shutting down, it will queue and later forward this request.
                    ReceiveRequest(message, target);
                }
            }
            catch (Exception ex)
            {
                try
                {
                    MessagingProcessingStatisticsGroup.OnDispatcherMessageProcessedError(message, "Non-existent activation");

                    var nea = ex as Catalog.NonExistentActivationException;
                    if (nea == null)
                    {
                        var str = String.Format("Error creating activation for {0}. Message {1}", message.NewGrainType, message);
                        logger.Error(ErrorCode.Dispatcher_ErrorCreatingActivation, str, ex);
                        throw new OrleansException(str, ex);
                    }

                    if (nea.IsStatelessWorker)
                    {
                        if (logger.IsEnabled(LogLevel.Debug))
                        {
                            logger.Debug(ErrorCode.Dispatcher_Intermediate_GetOrCreateActivation,
                                         String.Format("Intermediate StatelessWorker NonExistentActivation for message {0}", message), ex);
                        }
                    }
                    else
                    {
                        logger.Info(ErrorCode.Dispatcher_Intermediate_GetOrCreateActivation,
                                    String.Format("Intermediate NonExistentActivation for message {0}", message), ex);
                    }

                    ActivationAddress nonExistentActivation = nea.NonExistentActivation;

                    if (message.Direction != Message.Directions.Response)
                    {
                        // Un-register the target activation so we don't keep getting spurious messages.
                        // The time delay (one minute, as of this writing) is to handle the unlikely but possible race where
                        // this request snuck ahead of another request, with new placement requested, for the same activation.
                        // If the activation registration request from the new placement somehow sneaks ahead of this un-registration,
                        // we want to make sure that we don't un-register the activation we just created.
                        // We would add a counter here, except that there's already a counter for this in the Catalog.
                        // Note that this has to run in a non-null scheduler context, so we always queue it to the catalog's context
                        var origin = message.SendingSilo;
                        scheduler.QueueWorkItem(new ClosureWorkItem(
                                                    // don't use message.TargetAddress, cause it may have been removed from the headers by this time!
                                                    async() =>
                        {
                            try
                            {
                                await this.localGrainDirectory.UnregisterAfterNonexistingActivation(
                                    nonExistentActivation, origin);
                            }
                            catch (Exception exc)
                            {
                                logger.Warn(ErrorCode.Dispatcher_FailedToUnregisterNonExistingAct,
                                            String.Format("Failed to un-register NonExistentActivation {0}",
                                                          nonExistentActivation), exc);
                            }
                        },
                                                    "LocalGrainDirectory.UnregisterAfterNonexistingActivation"),
                                                catalog.SchedulingContext);

                        ProcessRequestToInvalidActivation(message, nonExistentActivation, null, "Non-existent activation");
                    }
                    else
                    {
                        logger.Warn(
                            ErrorCode.Dispatcher_NoTargetActivation,
                            nonExistentActivation.Silo.IsClient
                                ? "No target client {0} for response message: {1}. It's likely that the client recently disconnected."
                                : "No target activation {0} for response message: {1}",
                            nonExistentActivation,
                            message);

                        this.localGrainDirectory.InvalidateCacheEntry(nonExistentActivation);
                    }
                }
                catch (Exception exc)
                {
                    // Unable to create activation for this request - reject message
                    RejectMessage(message, Message.RejectionTypes.Transient, exc);
                }
            }
        }
Example #20
0
 public void ClearTargetAddress()
 {
     targetAddress = null;
 }
Example #21
0
        private async Task AddressMessageAsync(Message message, PlacementTarget target, PlacementStrategy strategy, ActivationAddress targetAddress)
        {
            var placementResult = await placementDirectorsManager.SelectOrAddActivation(
                message.SendingAddress, target, this.catalog, strategy);

            SetMessageTargetPlacement(message, placementResult, targetAddress);
        }
Example #22
0
 public DuplicateActivationException(ActivationAddress activationToUse)
     : base("DuplicateActivationException")
 {
     ActivationToUse = activationToUse;
 }
Example #23
0
        private void SetMessageTargetPlacement(Message message, PlacementResult placementResult, ActivationAddress targetAddress)
        {
            if (placementResult.IsNewPlacement && targetAddress.Grain.IsClient)
            {
                logger.Error(ErrorCode.Dispatcher_AddressMsg_UnregisteredClient, $"AddressMessage could not find target for client pseudo-grain {message}");
                throw new KeyNotFoundException($"Attempting to send a message {message} to an unregistered client pseudo-grain {targetAddress.Grain}");
            }

            message.SetTargetPlacement(placementResult);
            if (placementResult.IsNewPlacement)
            {
                CounterStatistic.FindOrCreate(StatisticNames.DISPATCHER_NEW_PLACEMENT).Increment();
            }
            if (logger.IsEnabled(LogLevel.Trace))
            {
                logger.Trace(ErrorCode.Dispatcher_AddressMsg_SelectTarget, "AddressMessage Placement SelectTarget {0}", message);
            }
        }
        /// <summary> Write a <c>ActivationAddress</c> value to the stream. </summary>
        internal void Write(ActivationAddress addr)
        {
            Write(addr.Silo ?? SiloAddress.Zero);

            // GrainId must not be null
            Write(addr.Grain);
            Write(addr.Activation ?? ActivationId.Zero);
        }
Example #25
0
        internal void OnDispatcherForwarding(Message message, ActivationAddress oldAddress, ActivationAddress forwardingAddress, string failedOperation, Exception exception)
        {
            if (this.IsEnabled(DispatcherForwardingEventName))
            {
                this.Write(DispatcherForwardingEventName, new { Message = message, OldAddress = oldAddress, ForwardingAddress = forwardingAddress, FailedOperation = failedOperation, Exception = exception });
            }

            if (this.IsEnabled(LogLevel.Information))
            {
                LogDispatcherForwarding(this, message, oldAddress, forwardingAddress, failedOperation, message.ForwardCount, exception);
            }

            MessagingProcessingStatisticsGroup.OnDispatcherMessageForwared(message);
        }
Example #26
0
        /// <summary>
        /// If activation already exists, use it
        /// Otherwise, create an activation of an existing grain by reading its state.
        /// Return immediately using a dummy that will queue messages.
        /// Concurrently start creating and initializing the real activation and replace it when it is ready.
        /// </summary>
        /// <param name="address">Grain's activation address</param>
        /// <param name="newPlacement">Creation of new activation was requested by the placement director.</param>
        /// <param name="grainType">The type of grain to be activated or created</param>
        /// <param name="genericArguments">Specific generic type of grain to be activated or created</param>
        /// <param name="activatedPromise"></param>
        /// <returns></returns>
        public ActivationData GetOrCreateActivation(
            ActivationAddress address,
            bool newPlacement,
            string grainType,
            string genericArguments,
            out Task activatedPromise)
        {
            ActivationData result;
            activatedPromise = TaskDone.Done;
            lock (activations)
            {
                if (TryGetActivationData(address.Activation, out result))
                {
                    ActivationCollector.TryRescheduleCollection(result);
                    return result;
                }
                
                if (newPlacement && !SiloStatusOracle.CurrentStatus.IsTerminating())
                {
                    // create a dummy activation that will queue up messages until the real data arrives
                    PlacementStrategy placement;
                    int typeCode = address.Grain.GetTypeCode();
                    string actualGrainType = null;

                    if (typeCode != 0) // special case for Membership grain.
                        GetGrainTypeInfo(typeCode, out actualGrainType, out placement);
                    else
                        placement = SystemPlacement.Singleton;

                    if (string.IsNullOrEmpty(grainType))
                    {
                        grainType = actualGrainType;
                    }

                    // We want to do this (RegisterMessageTarget) under the same lock that we tested TryGetActivationData. They both access ActivationDirectory.
                    result = new ActivationData(
                        address, 
                        genericArguments, 
                        placement, 
                        ActivationCollector, 
                        config.Application.GetCollectionAgeLimit(grainType));
                    RegisterMessageTarget(result);
                }
            } // End lock

            // Did not find and did not start placing new
            if (result == null)
            {
                var msg = String.Format("Non-existent activation: {0}, grain type: {1}.",
                                           address.ToFullString(), grainType);
                if (logger.IsVerbose) logger.Verbose(ErrorCode.CatalogNonExistingActivation2, msg);
                CounterStatistic.FindOrCreate(StatisticNames.CATALOG_ACTIVATION_NON_EXISTENT_ACTIVATIONS).Increment();
                throw new NonExistentActivationException(msg) { NonExistentActivation = address };
            }
   
            SetupActivationInstance(result, grainType, genericArguments);
            activatedPromise = InitActivation(result, grainType, genericArguments);
            return result;
        }
Example #27
0
        internal void OnDispatcherForwardingFailed(Message message, ActivationAddress oldAddress, ActivationAddress forwardingAddress, string failedOperation, Exception exception)
        {
            if (this.IsEnabled(DispatcherForwardingFailedEventName))
            {
                this.Write(DispatcherForwardingFailedEventName, new { Message = message, OldAddress = oldAddress, ForwardingAddress = forwardingAddress, FailedOperation = failedOperation, Exception = exception });
            }

            LogDispatcherForwardingFailed(this, message, oldAddress, forwardingAddress, failedOperation, message.ForwardCount, exception);
        }
Example #28
0
 internal void ProcessRequestToInvalidActivation(
     Message message, 
     ActivationAddress oldAddress, 
     ActivationAddress forwardingAddress, 
     string failedOperation, 
     Exception exc = null)
 {
     // Just use this opportunity to invalidate local Cache Entry as well. 
     if (oldAddress != null)
     {
         Silo.CurrentSilo.LocalGrainDirectory.InvalidateCacheEntry(oldAddress);
     }
     // IMPORTANT: do not do anything on activation context anymore, since this activation is invalid already.
     Scheduler.QueueWorkItem(new ClosureWorkItem(
         () => TryForwardRequest(message, oldAddress, forwardingAddress, failedOperation, exc)),
         catalog.SchedulingContext);
 }
Example #29
0
        internal void OnDispatcherForwardingMultiple(int messageCount, ActivationAddress oldAddress, ActivationAddress forwardingAddress, string failedOperation, Exception exception)
        {
            if (this.IsEnabled(DispatcherForwardingMultipleEventName))
            {
                this.Write(DispatcherForwardingMultipleEventName, new { MessageCount = messageCount, OldAddress = oldAddress, ForwardingAddress = forwardingAddress, FailedOperation = failedOperation, Exception = exception });
            }

            if (this.IsEnabled(LogLevel.Information))
            {
                LogDispatcherForwardingMultiple(this, messageCount, oldAddress, forwardingAddress, failedOperation, exception);
            }
        }
Example #30
0
        internal void TryForwardRequest(Message message, ActivationAddress oldAddress, ActivationAddress forwardingAddress, string failedOperation, Exception exc = null)
        {
            bool forwardingSucceded = true;
            try
            {
                logger.Info(ErrorCode.Messaging_Dispatcher_TryForward, 
                    String.Format("Trying to forward after {0}, ForwardCount = {1}. Message {2}.", failedOperation, message.ForwardCount, message));

                MessagingProcessingStatisticsGroup.OnDispatcherMessageReRouted(message);
                if (oldAddress != null)
                {
                    message.AddToCacheInvalidationHeader(oldAddress);
                }
                forwardingSucceded = InsideRuntimeClient.Current.TryForwardMessage(message, forwardingAddress);
            }
            catch (Exception exc2)
            {
                forwardingSucceded = false;
                exc = exc2;
            }
            finally
            {
                if (!forwardingSucceded)
                {
                    var str = String.Format("Forwarding failed: tried to forward message {0} for {1} times after {2} to invalid activation. Rejecting now.", 
                        message, message.ForwardCount, failedOperation);
                    logger.Warn(ErrorCode.Messaging_Dispatcher_TryForwardFailed, str, exc);
                    RejectMessage(message, Message.RejectionTypes.Transient, exc, str);
                }
            }
        }
Example #31
0
        internal void TryForwardRequest(Message message, ActivationAddress oldAddress, ActivationAddress forwardingAddress, string failedOperation, Exception exc = null)
        {
            bool forwardingSucceded = false;

            try
            {
                this.messagingTrace.OnDispatcherForwarding(message, oldAddress, forwardingAddress, failedOperation, exc);

                if (oldAddress != null)
                {
                    message.AddToCacheInvalidationHeader(oldAddress);
                }

                forwardingSucceded = this.TryForwardMessage(message, forwardingAddress);
            }
            catch (Exception exc2)
            {
                forwardingSucceded = false;
                exc = exc2;
            }
            finally
            {
                var sentRejection = false;

                // If the message was a one-way message, send a cache invalidation response even if the message was successfully forwarded.
                if (message.Direction == Message.Directions.OneWay)
                {
                    this.RejectMessage(
                        message,
                        Message.RejectionTypes.CacheInvalidation,
                        exc,
                        "OneWay message sent to invalid activation");
                    sentRejection = true;
                }

                if (!forwardingSucceded)
                {
                    this.messagingTrace.OnDispatcherForwardingFailed(message, oldAddress, forwardingAddress, failedOperation, exc);
                    if (!sentRejection)
                    {
                        var str = $"Forwarding failed: tried to forward message {message} for {message.ForwardCount} times after {failedOperation} to invalid activation. Rejecting now.";
                        RejectMessage(message, Message.RejectionTypes.Transient, exc, str);
                    }
                }
            }
        }
Example #32
0
 public void ClearTargetAddress()
 {
     targetAddress = null;
 }
Example #33
0
 public bool Matches(ActivationAddress other)
 {
     return Equals(Grain, other.Grain) && Equals(Activation, other.Activation);
 }
Example #34
0
        private void ResendMessageImpl(Message message, ActivationAddress forwardingAddress = null)
        {
            if (logger.IsVerbose) logger.Verbose("Resend {0}", message);
            message.SetMetadata(Message.Metadata.TARGET_HISTORY, message.GetTargetHistory());

            if (message.TargetGrain.IsSystemTarget)
            {
                dispatcher.SendSystemTargetMessage(message);
            }
            else if (forwardingAddress != null)
            {
                message.TargetAddress = forwardingAddress;
                message.RemoveHeader(Message.Header.IS_NEW_PLACEMENT);
                dispatcher.Transport.SendMessage(message);
            }
            else
            {
                message.RemoveHeader(Message.Header.TARGET_ACTIVATION);
                message.RemoveHeader(Message.Header.TARGET_SILO);
                dispatcher.SendMessage(message);
            }
        }
Example #35
0
 private ActivationAddress GetClientActivationAddress(GrainId clientId)
 {
     return(ActivationAddress.GetAddress(myAddress, clientId, ActivationId.GetActivationId(clientId)));
 }