Exemplo n.º 1
0
        public async Task <AddressAndTag> RegisterAsync(GrainAddress address, int hopCount)
        {
            var counterStatistic = hopCount > 0 ? this.RegistrationsSingleActRemoteReceived : this.registrationsSingleActIssued;

            counterStatistic.Increment();

            // see if the owner is somewhere else (returns null if we are owner)
            var forwardAddress = this.CheckIfShouldForward(address.GrainId, hopCount, "RegisterAsync");

            // on all silos other than first, we insert a retry delay and recheck owner before forwarding
            if (hopCount > 0 && forwardAddress != null)
            {
                await Task.Delay(RETRY_DELAY);

                forwardAddress = this.CheckIfShouldForward(address.GrainId, hopCount, "RegisterAsync");
                if (forwardAddress is object)
                {
                    int hash = unchecked ((int)address.GrainId.GetUniformHashCode());
                    this.log.LogWarning($"RegisterAsync - It seems we are not the owner of activation {address} (hash: {hash:X}), trying to forward it to {forwardAddress} (hopCount={hopCount})");
                }
            }

            if (forwardAddress == null)
            {
                RegistrationsSingleActLocal.Increment();

                var result = DirectoryPartition.AddSingleActivation(address);
                return(result);
            }
            else
            {
                RegistrationsSingleActRemoteSent.Increment();

                // otherwise, notify the owner
                AddressAndTag result = await GetDirectoryReference(forwardAddress).RegisterAsync(address, hopCount + 1);

                // Caching optimization:
                // cache the result of a successfull RegisterSingleActivation call, only if it is not a duplicate activation.
                // this way next local lookup will find this ActivationAddress in the cache and we will save a full lookup!
                if (result.Address == null)
                {
                    return(result);
                }

                if (!address.Equals(result.Address) || !IsValidSilo(address.SiloAddress))
                {
                    return(result);
                }

                // update the cache so next local lookup will find this ActivationAddress in the cache and we will save full lookup.
                DirectoryCache.AddOrUpdate(address, result.VersionTag);

                return(result);
            }
        }