Пример #1
0
        private async ValueTask <PlacementResult> GetOrPlaceActivationAsync(
            ValueTask <PlacementResult> selectActivationTask,
            PlacementTarget target,
            PlacementStrategy strategy,
            IPlacementRuntime placementRuntime,
            IPlacementDirector director)
        {
            var placementResult = await selectActivationTask;

            if (placementResult is object)
            {
                return(placementResult);
            }

            var siloAddress = await director.OnAddActivation(strategy, target, placementRuntime);

            ActivationId activationId;

            if (strategy.IsDeterministicActivationId)
            {
                // Use the grain id as the activation id.
                activationId = ActivationId.GetDeterministic(target.GrainIdentity);
            }
            else
            {
                activationId = ActivationId.NewId();
            }

            return(PlacementResult.SpecifyCreation(
                       siloAddress,
                       activationId,
                       strategy));
        }
Пример #2
0
        private async Task <PlacementResult> AddActivation(
            PlacementTarget target,
            IPlacementRuntime context,
            PlacementStrategy strategy)
        {
            if (target.IsClient)
            {
                throw new InvalidOperationException("Client grains are not activated using the placement subsystem.");
            }

            var director    = ResolveDirector(strategy);
            var siloAddress = await director.OnAddActivation(strategy, target, context);

            var grainTypeName = context.GetGrainTypeName(((LegacyGrainId)target.GrainIdentity).TypeCode);

            ActivationId activationId;

            if (strategy.IsDeterministicActivationId)
            {
                // Use the grain id as the activation id.
                activationId = ActivationId.GetDeterministic(target.GrainIdentity);
            }
            else
            {
                activationId = ActivationId.NewId();
            }

            return(PlacementResult.SpecifyCreation(
                       siloAddress,
                       activationId,
                       strategy,
                       grainTypeName));
        }
        public virtual async Task <PlacementResult> OnSelectActivation(
            PlacementStrategy strategy, GrainId target, IPlacementRuntime context)
        {
            List <ActivationAddress> places = (await context.FullLookup(target)).Addresses;

            return(ChooseRandomActivation(places, context));
        }
Пример #4
0
        public async Task <PlacementResult> SelectOrAddActivation(
            PlacementTarget targetGrain,
            IPlacementRuntime context,
            PlacementStrategy strategy)
        {
            if (targetGrain.IsClient)
            {
                var res = await clientObserversPlacementDirector.OnSelectActivation(strategy, (GrainId)targetGrain.GrainIdentity, context);

                if (res == null)
                {
                    throw new ClientNotAvailableException(targetGrain.GrainIdentity);
                }
                return(res);
            }

            var actualStrategy = strategy ?? defaultPlacementStrategy;
            var director       = ResolveSelector(actualStrategy);
            var result         = await director.OnSelectActivation(strategy, targetGrain.GrainIdentity, context);

            if (result != null)
            {
                return(result);
            }

            return(await AddActivation(targetGrain, context, actualStrategy));
        }
Пример #5
0
        public static PlacementStrategy GetGrainPlacementStrategy(this IPlacementRuntime @this, int typeCode, string genericArguments = null)
        {
            string            unused;
            PlacementStrategy placement;

            @this.GetGrainTypeInfo(typeCode, out unused, out placement, genericArguments);
            return(placement);
        }
Пример #6
0
        public static string GetGrainTypeName(this IPlacementRuntime @this, int typeCode, string genericArguments = null)
        {
            string            grainClass;
            PlacementStrategy unused;

            @this.GetGrainTypeInfo(typeCode, out grainClass, out unused, genericArguments);
            return(grainClass);
        }
Пример #7
0
        public static PlacementStrategy GetGrainPlacementStrategy(this IPlacementRuntime @this, int typeCode, string genericArguments = null)
        {
            string            unused;
            PlacementStrategy placement;
            MultiClusterRegistrationStrategy unusedActivationStrategy;

            @this.GetGrainTypeInfo(typeCode, out unused, out placement, out unusedActivationStrategy, genericArguments);
            return(placement);
        }
Пример #8
0
        private Task <PlacementResult> SelectActivation(
            GrainId targetGrain,
            IPlacementRuntime context,
            PlacementStrategy strategy)
        {
            var director = ResolveSelector(strategy);

            return(director.OnSelectActivation(strategy, targetGrain, context));
        }
Пример #9
0
        public bool TrySelectActivationSynchronously(
            PlacementStrategy strategy, GrainId target, IPlacementRuntime context, out PlacementResult placementResult)
        {
            if (context.FastLookup(target, out var addresses))
            {
                placementResult = ChooseRandomActivation(addresses, context);
                return(true);
            }

            placementResult = null;
            return(false);
        }
Пример #10
0
        private async Task <PlacementResult> AddActivation(
            PlacementTarget target,
            IPlacementRuntime context,
            PlacementStrategy strategy)
        {
            if (target.IsClient)
            {
                throw new InvalidOperationException("Client grains are not activated using the placement subsystem.");
            }

            var director = ResolveDirector(strategy);

            return(PlacementResult.SpecifyCreation(
                       await director.OnAddActivation(strategy, target, context),
                       strategy,
                       context.GetGrainTypeName(target.GrainIdentity.TypeCode)));
        }
Пример #11
0
        private async ValueTask <PlacementResult> GetOrPlaceActivationAsync(
            PlacementTarget target,
            PlacementStrategy strategy,
            IPlacementRuntime placementRuntime,
            IActivationSelector selector,
            IPlacementDirector director)
        {
            var placementResult = await selector.OnSelectActivation(strategy, target.GrainIdentity, placementRuntime);

            if (placementResult is object)
            {
                return(placementResult);
            }

            var siloAddress = await director.OnAddActivation(strategy, target, placementRuntime);

            string grainTypeName;

            if (LegacyGrainId.TryConvertFromGrainId(target.GrainIdentity, out var legacyId))
            {
                grainTypeName = placementRuntime.GetGrainTypeName(legacyId.TypeCode);
            }
            else
            {
                grainTypeName = null;
            }

            ActivationId activationId;

            if (strategy.IsDeterministicActivationId)
            {
                // Use the grain id as the activation id.
                activationId = ActivationId.GetDeterministic(target.GrainIdentity);
            }
            else
            {
                activationId = ActivationId.NewId();
            }

            return(PlacementResult.SpecifyCreation(
                       siloAddress,
                       activationId,
                       strategy,
                       grainTypeName));
        }
Пример #12
0
        public virtual ValueTask <PlacementResult> OnSelectActivation(
            PlacementStrategy strategy,
            GrainId target,
            IPlacementRuntime context)
        {
            if (context.FastLookup(target, out var addresses))
            {
                var placementResult = ChooseRandomActivation(addresses, context);
                return(new ValueTask <PlacementResult>(placementResult));
            }

            return(SelectActivationAsync(target, context));

            async ValueTask <PlacementResult> SelectActivationAsync(GrainId target, IPlacementRuntime context)
            {
                var places = await context.FullLookup(target);

                return(ChooseRandomActivation(places, context));
            }
        }
Пример #13
0
        public bool TrySelectActivationSynchronously(
            ActivationAddress sendingAddress,
            PlacementTarget targetGrain,
            IPlacementRuntime context,
            PlacementStrategy strategy,
            out PlacementResult placementResult)
        {
            if (targetGrain.IsClient)
            {
                return(clientObserversPlacementDirector.TrySelectActivationSynchronously(
                           strategy,
                           (GrainId)targetGrain.GrainIdentity,
                           context,
                           out placementResult));
            }

            var actualStrategy = strategy ?? defaultPlacementStrategy;
            var director       = ResolveSelector(actualStrategy);

            return(director.TrySelectActivationSynchronously(strategy, (GrainId)targetGrain.GrainIdentity, context, out placementResult));
        }
Пример #14
0
        public Task <PlacementResult> OnSelectActivation(
            PlacementStrategy strategy, GrainId target, IPlacementRuntime context)
        {
            if (target.IsClient)
            {
                throw new InvalidOperationException("Cannot use StatelessWorkerStrategy to route messages to client grains.");
            }

            // If there are available (not busy with a request) activations, it returns the first one.
            // If all are busy and the number of local activations reached or exceeded MaxLocal, it randomly returns one of them.
            // Otherwise, it requests creation of a new activation.
            List <ActivationData> local;

            if (!context.LocalLookup(target, out local) || local.Count == 0)
            {
                return(Task.FromResult((PlacementResult)null));
            }

            var placement = (StatelessWorkerPlacement)strategy;

            foreach (var activation in local)
            {
                ActivationData info;
                if (!context.TryGetActivationData(activation.ActivationId, out info) ||
                    info.State != ActivationState.Valid || !info.IsInactive)
                {
                    continue;
                }

                return(Task.FromResult(PlacementResult.IdentifySelection(ActivationAddress.GetAddress(context.LocalSilo, target, activation.ActivationId))));
            }

            if (local.Count >= placement.MaxLocal)
            {
                var id = local[local.Count == 1 ? 0 : random.Next(local.Count)].ActivationId;
                return(Task.FromResult(PlacementResult.IdentifySelection(ActivationAddress.GetAddress(context.LocalSilo, target, id))));
            }

            return(Task.FromResult((PlacementResult)null));
        }
        protected PlacementResult ChooseRandomActivation(List <ActivationAddress> places, IPlacementRuntime context)
        {
            if (places.Count <= 0)
            {
                // we return null to indicate that we were unable to select a target from places activations.
                return(null);
            }
            if (places.Count == 1)
            {
                return(PlacementResult.IdentifySelection(places[0]));
            }
            // places.Count >= 2
            // Choose randomly if there is one, else make a new activation of the target
            // pick local if available (consider making this a purely random assignment of grains).
            var here  = context.LocalSilo;
            var local = places.Where(a => a.Silo.Equals(here)).ToList();

            if (local.Count > 0)
            {
                return(PlacementResult.IdentifySelection(local[random.Next(local.Count)]));
            }

            return(PlacementResult.IdentifySelection(places[random.Next(places.Count)]));
        }
Пример #16
0
        public static Task <AddressesAndTag> Lookup(this IPlacementRuntime @this, GrainId grainId)
        {
            AddressesAndTag l;

            return(@this.FastLookup(grainId, out l) ? Task.FromResult(l) : @this.FullLookup(grainId));
        }
Пример #17
0
 public static PlacementStrategy GetGrainPlacementStrategy(this IPlacementRuntime @this, GrainId grainId, string genericArguments = null)
 {
     return(@this.GetGrainPlacementStrategy(grainId.TypeCode, genericArguments));
 }
        /// <summary>
        /// Selects the best match from list of silos, updates local statistics.
        /// </summary>
        /// <note>
        /// This is equivalent with SelectSiloPowerOfK() with chooseHowMany = #Silos
        /// </note>
        private Task <SiloAddress> SelectSiloGreedy(PlacementStrategy strategy, GrainId grain, IPlacementRuntime context)
        {
            int             minLoad       = int.MaxValue;
            CachedLocalStat minLoadedSilo = null;

            foreach (CachedLocalStat current in localCache.Values)
            {
                if (IsSiloOverloaded(current.SiloStats))
                {
                    continue;
                }

                int load = SiloLoad_ByRecentActivations(current);
                if (load >= minLoad)
                {
                    continue;
                }

                minLoadedSilo = current;
                minLoad       = load;
            }

            if (minLoadedSilo != null)
            {
                return(MakePlacement(minLoadedSilo));
            }

            var debugLog = string.Format("Unable to select a candidate from {0} silos: {1}", localCache.Count,
                                         Utils.EnumerableToString(
                                             localCache,
                                             kvp => String.Format("SiloAddress = {0} -> {1}", kvp.Key.ToString(), kvp.Value.ToString())));

            logger.Warn(ErrorCode.Placement_ActivationCountBasedDirector_NoSilos, debugLog);
            throw new OrleansException(debugLog);
        }
Пример #19
0
 public static string GetGrainTypeName(this IPlacementRuntime @this, int typeCode, string genericArguments = null)
 {
     ((Catalog)@this).GetGrainTypeInfo(typeCode, out var grainClass, genericArguments);
     return(grainClass);
 }
        public override async Task <PlacementResult> OnSelectActivation(PlacementStrategy strategy, GrainId target, IPlacementRuntime context)
        {
            // no need to check if we can find an activation for this client in the cache or local directory partition
            // as TrySelectActivationSynchronously which checks for that should have been called before
            AddressesAndTag addresses;

            // we need to look up the directory entry for this grain on a remote silo
            switch (target.Category)
            {
            case UniqueKey.Category.Client:
            {
                addresses = await context.FullLookup(target);

                return(ChooseRandomActivation(addresses.Addresses, context));
            }

            case UniqueKey.Category.GeoClient:
            {
                // we need to look up the activations in the remote cluster
                addresses = await context.LookupInCluster(target, target.Key.ClusterId);

                return(ChooseRandomActivation(addresses.Addresses, context));
            }

            default:
                throw new InvalidOperationException("Unsupported client type. Grain " + target);
            }
        }
Пример #21
0
        /// <summary>
        /// Gets or places an activation.
        /// </summary>
        public ValueTask <PlacementResult> GetOrPlaceActivation(PlacementTarget target, IPlacementRuntime placementRuntime)
        {
            var strategy = _strategyResolver.GetPlacementStrategy(target.GrainIdentity.Type);
            var director = _directorResolver.GetPlacementDirector(strategy);
            var selector = director as IActivationSelector ?? _defaultActivationSelector;

            if (selector.TrySelectActivationSynchronously(strategy, target.GrainIdentity, placementRuntime, out var placementResult))
            {
                return(new ValueTask <PlacementResult>(placementResult));
            }

            return(GetOrPlaceActivationAsync(target, strategy, placementRuntime, selector, director));
        }
Пример #22
0
        public override async Task <PlacementResult> OnSelectActivation(PlacementStrategy strategy, GrainId target, IPlacementRuntime context)
        {
            // no need to check if we can find an activation for this client in the cache or local directory partition
            // as TrySelectActivationSynchronously which checks for that should have been called before
            List <ActivationAddress> addresses;

            // we need to look up the directory entry for this grain on a remote silo
            if (!ClientGrainId.TryParse(target, out var clientId))
            {
                throw new InvalidOperationException($"Unsupported id format: {target}");
            }

            addresses = await context.FullLookup(clientId.GrainId);

            return(ChooseRandomActivation(addresses, context));
        }
Пример #23
0
 public static string GetGrainTypeName(this IPlacementRuntime @this, GrainId grainId, string genericArguments = null)
 {
     return(@this.GetGrainTypeName(grainId.TypeCode, genericArguments));
 }
Пример #24
0
 public static void GetGrainTypeInfo(this IPlacementRuntime @this, GrainId grainId, out string grainClass, out PlacementStrategy placement, out MultiClusterRegistrationStrategy activationStrategy, string genericArguments = null)
 {
     @this.GetGrainTypeInfo(grainId.TypeCode, out grainClass, out placement, out activationStrategy, genericArguments);
 }
Пример #25
0
        public override ValueTask <PlacementResult> OnSelectActivation(PlacementStrategy strategy, GrainId target, IPlacementRuntime context)
        {
            if (!ClientGrainId.TryParse(target, out var clientId))
            {
                throw new InvalidOperationException($"Unsupported id format: {target}");
            }

            var grainId = clientId.GrainId;

            if (context.FastLookup(grainId, out var addresses))
            {
                var placementResult = ChooseRandomActivation(addresses, context);
                return(new ValueTask <PlacementResult>(placementResult));
            }

            return(SelectActivationAsync(grainId, context));

            async ValueTask <PlacementResult> SelectActivationAsync(GrainId target, IPlacementRuntime context)
            {
                var places = await context.FullLookup(target);

                return(ChooseRandomActivation(places, context));
            }
        }
Пример #26
0
 public Task <PlacementResult> OnSelectActivation(
     PlacementStrategy strategy, GrainId target, IPlacementRuntime context)
 {
     return(Task.FromResult(SelectActivationCore(strategy, target, context)));
 }
Пример #27
0
 public static void GetGrainTypeInfo(this IPlacementRuntime @this, GrainId grainId, out string grainClass, out PlacementStrategy placement, string genericArguments = null)
 {
     @this.GetGrainTypeInfo(grainId.TypeCode, out grainClass, out placement, genericArguments);
 }
Пример #28
0
 public ValueTask <PlacementResult> OnSelectActivation(PlacementStrategy strategy, GrainId target, IPlacementRuntime context) => new ValueTask <PlacementResult>(SelectActivationCore(strategy, target, context));
Пример #29
0
 public bool TrySelectActivationSynchronously(
     PlacementStrategy strategy, GrainId target, IPlacementRuntime context, out PlacementResult placementResult)
 {
     placementResult = SelectActivationCore(strategy, target, context);
     return(placementResult != null);
 }
Пример #30
0
        /// <summary>
        /// Gets or places an activation.
        /// </summary>
        public ValueTask <PlacementResult> GetOrPlaceActivation(PlacementTarget target, IPlacementRuntime placementRuntime)
        {
            var strategy = _strategyResolver.GetPlacementStrategy(target.GrainIdentity.Type);
            var director = _directorResolver.GetPlacementDirector(strategy);
            var selector = director as IActivationSelector ?? _defaultActivationSelector;

            var selectActivationTask = selector.OnSelectActivation(strategy, target.GrainIdentity, placementRuntime);

            if (selectActivationTask.IsCompletedSuccessfully && selectActivationTask.Result is object)
            {
                return(selectActivationTask);
            }

            return(GetOrPlaceActivationAsync(selectActivationTask, target, strategy, placementRuntime, director));
        }