示例#1
0
 private ActivationAddress(SiloAddress silo, GrainId grain, ActivationId activation, MultiClusterStatus status)
 {
     Silo = silo;
     Grain = grain;
     Activation = activation;
     Status = status;
 }
示例#2
0
        public static ActivationAddress GetAddress(SiloAddress silo, GrainId grain, ActivationId activation)
        {
            // Silo part is not mandatory
            if (grain == null) throw new ArgumentNullException("grain");

            return new ActivationAddress(silo, grain, activation);
        }
示例#3
0
 public ProxiedMessageCenter(ClientConfiguration config, IPAddress localAddress, int gen, GrainId clientId, IGatewayListProvider gatewayListProvider)
 {
     lockable = new object();
     MyAddress = SiloAddress.New(new IPEndPoint(localAddress, 0), gen);
     ClientId = clientId;
     Running = false;
     MessagingConfiguration = config;
     GatewayManager = new GatewayManager(config, gatewayListProvider);
     PendingInboundMessages = new RuntimeQueue<Message>();
     gatewayConnections = new Dictionary<Uri, GatewayConnection>();
     numMessages = 0;
     grainBuckets = new WeakReference[config.ClientSenderBuckets];
     logger = TraceLogger.GetLogger("Messaging.ProxiedMessageCenter", TraceLogger.LoggerType.Runtime);
     if (logger.IsVerbose) logger.Verbose("Proxy grain client constructed");
     IntValueStatistic.FindOrCreate(StatisticNames.CLIENT_CONNECTED_GATEWAY_COUNT, () =>
         {
             lock (gatewayConnections)
             {
                 return gatewayConnections.Values.Count(conn => conn.IsLive);
             }
         });
     if (StatisticsCollector.CollectQueueStats)
     {
         queueTracking = new QueueTrackingStatistic("ClientReceiver");
     }
 }
示例#4
0
        public static ActivationAddress GetAddress(SiloAddress silo, GrainId grain, ActivationId activation, MultiClusterStatus status = MultiClusterStatus.Owned)
        {
            // Silo part is not mandatory
            if (grain == null) throw new ArgumentNullException("grain");

            return new ActivationAddress(silo, grain, activation, status);
        }
        public async Task<RemoteClusterActivationResponse> ProcessActivationRequest(GrainId grain, string requestClusterId, int hopCount = 0)
        {
            // check if the requesting cluster id is in the current configuration view of this cluster
            // if not, reject the message.
            var multiClusterConfiguration = Runtime.Silo.CurrentSilo.LocalMultiClusterOracle?.GetMultiClusterConfiguration();
            if (multiClusterConfiguration == null || !multiClusterConfiguration.Clusters.Contains(requestClusterId))       
            {
                logger.Warn(ErrorCode.GlobalSingleInstance_WarningInvalidOrigin, 
                    "GSIP:Rsp {0} Origin={1} GSI request rejected because origin is not in MC configuration", grain.ToString(), requestClusterId);

                return new RemoteClusterActivationResponse(ActivationResponseStatus.Failed);
            }

            var forwardAddress = router.CheckIfShouldForward(grain, 0, "ProcessActivationRequest");

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

            if (forwardAddress == null)
            {
                return ProcessRequestLocal(grain, requestClusterId);
            }
            else
            {
                if (logger.IsVerbose2)
                    logger.Verbose("GSIP:Rsp {0} Origin={1} forward to {2}", grain.ToString(), requestClusterId, forwardAddress);

                var clusterGrainDir = InsideRuntimeClient.Current.InternalGrainFactory.GetSystemTarget<IClusterGrainDirectory>(Constants.ClusterDirectoryServiceId, forwardAddress);
                return await clusterGrainDir.ProcessActivationRequest(grain, requestClusterId, hopCount + 1);
            }
        }
 public ClusterGrainDirectory(LocalGrainDirectory r, GrainId grainId, string clusterId, bool lowPriority)
     : base(grainId, r.MyAddress, lowPriority)
 {
     this.router = r;        
     this.clusterId = clusterId;
     this.logger = r.Logger;
 }
        internal override Task<PlacementResult> OnSelectActivation(
            PlacementStrategy strategy, GrainId target, IPlacementContext 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);
        }
示例#8
0
        private static readonly TimeSpan RETRY_DELAY = TimeSpan.FromSeconds(5); // Pause 5 seconds between forwards to let the membership directory settle down

        internal RemoteGrainDirectory(LocalGrainDirectory r, GrainId id)
            : base(id, r.MyAddress)
        {
            router = r;
            partition = r.DirectoryPartition;
            logger = TraceLogger.GetLogger("Orleans.GrainDirectory.CacheValidator", TraceLogger.LoggerType.Runtime);
        }
        public override async Task<PlacementResult> OnSelectActivation(PlacementStrategy strategy, GrainId target, IPlacementContext context)
        {
            // first, check if we can find an activation for this client in the cache or local directory partition
            AddressesAndTag addresses;
            if (context.FastLookup(target, out addresses))
                return ChooseRandomActivation(addresses.Addresses, context);

            // 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);
            }
        }
        internal PersistentStreamPullingAgent(
            GrainId id, 
            string strProviderName,
            IStreamProviderRuntime runtime,
            IStreamPubSub streamPubSub,
            QueueId queueId,
            PersistentStreamProviderConfig config)
            : base(id, runtime.ExecutingSiloAddress, true)
        {
            if (runtime == null) throw new ArgumentNullException("runtime", "PersistentStreamPullingAgent: runtime reference should not be null");
            if (strProviderName == null) throw new ArgumentNullException("runtime", "PersistentStreamPullingAgent: strProviderName should not be null");

            QueueId = queueId;
            streamProviderName = strProviderName;
            providerRuntime = runtime;
            pubSub = streamPubSub;
            pubSubCache = new Dictionary<StreamId, StreamConsumerCollection>();
            safeRandom = new SafeRandom();
            this.config = config;
            numMessages = 0;

            logger = providerRuntime.GetLogger(GrainId + "-" + streamProviderName);
            logger.Info((int)ErrorCode.PersistentStreamPullingAgent_01, 
                "Created {0} {1} for Stream Provider {2} on silo {3} for Queue {4}.",
                GetType().Name, GrainId.ToDetailedString(), streamProviderName, Silo, QueueId.ToStringWithHashCode());

            string statUniquePostfix = strProviderName + "." + QueueId;
            numReadMessagesCounter = CounterStatistic.FindOrCreate(new StatisticName(StatisticNames.STREAMS_PERSISTENT_STREAM_NUM_READ_MESSAGES, statUniquePostfix));
            numSentMessagesCounter = CounterStatistic.FindOrCreate(new StatisticName(StatisticNames.STREAMS_PERSISTENT_STREAM_NUM_SENT_MESSAGES, statUniquePostfix));
            IntValueStatistic.FindOrCreate(new StatisticName(StatisticNames.STREAMS_PERSISTENT_STREAM_PUBSUB_CACHE_SIZE, statUniquePostfix), () => pubSubCache.Count);
            // TODO: move queue cache size statistics tracking into queue cache implementation once Telemetry APIs and LogStatistics have been reconciled.
            //IntValueStatistic.FindOrCreate(new StatisticName(StatisticNames.STREAMS_PERSISTENT_STREAM_QUEUE_CACHE_SIZE, statUniquePostfix), () => queueCache != null ? queueCache.Size : 0);
        }
示例#11
0
 protected SystemTarget(GrainId grainId, SiloAddress silo, bool lowPriority)
 {
     GrainId = grainId;
     Silo = silo;
     ActivationId = ActivationId.GetSystemActivation(grainId, silo);
     SchedulingContext = new SchedulingContext(this, lowPriority);
 }
        internal PersistentStreamPullingAgent(
            GrainId id, 
            string strProviderName,
            IStreamProviderRuntime runtime,
            QueueId queueId, 
            TimeSpan queueGetPeriod,
            TimeSpan initQueueTimeout,
            TimeSpan maxDeliveryTime)
            : base(id, runtime.ExecutingSiloAddress, true)
        {
            if (runtime == null) throw new ArgumentNullException("runtime", "PersistentStreamPullingAgent: runtime reference should not be null");
            if (strProviderName == null) throw new ArgumentNullException("runtime", "PersistentStreamPullingAgent: strProviderName should not be null");

            QueueId = queueId;
            streamProviderName = strProviderName;
            providerRuntime = runtime;
            pubSub = runtime.PubSub(StreamPubSubType.GrainBased);
            pubSubCache = new Dictionary<StreamId, StreamConsumerCollection>();
            safeRandom = new SafeRandom();
            this.queueGetPeriod = queueGetPeriod;
            this.initQueueTimeout = initQueueTimeout;
            this.maxDeliveryTime = maxDeliveryTime;
            numMessages = 0;

            logger = providerRuntime.GetLogger(GrainId + "-" + streamProviderName);
            logger.Info((int)ErrorCode.PersistentStreamPullingAgent_01, 
                "Created {0} {1} for Stream Provider {2} on silo {3} for Queue {4}.",
                GetType().Name, GrainId.ToDetailedString(), streamProviderName, Silo, QueueId.ToStringWithHashCode());

            numReadMessagesCounter = CounterStatistic.FindOrCreate(new StatisticName(StatisticNames.STREAMS_PERSISTENT_STREAM_NUM_READ_MESSAGES, strProviderName));
            numSentMessagesCounter = CounterStatistic.FindOrCreate(new StatisticName(StatisticNames.STREAMS_PERSISTENT_STREAM_NUM_SENT_MESSAGES, strProviderName));
        }
示例#13
0
 internal override Task<PlacementResult> OnAddActivation(
     PlacementStrategy strategy, GrainId grain, IPlacementContext context)
 {
     var grainType = context.GetGrainTypeName(grain);
     var allSilos = context.AllActiveSilos;
     return Task.FromResult(
         PlacementResult.SpecifyCreation(allSilos[random.Next(allSilos.Count)], strategy, grainType));
 }
        private GlobalSingleInstanceResponseTracker(Task<RemoteClusterActivationResponse>[] responsePromises, GrainId grain, Logger logger)
        {
            this.responsePromises = responsePromises;
            this.grain = grain;
            this.logger = logger;

            CheckIfDone();
        }
 internal void ClientDropped(GrainId clientId)
 {
     var addr = GetClientActivationAddress(clientId);
     scheduler.QueueTask(
         () => ExecuteWithRetries(() => grainDirectory.UnregisterAsync(addr, force:true), ErrorCode.ClientRegistrarFailedToUnregister, String.Format("Directory.UnRegisterAsync {0} failed.", addr)), 
         this.SchedulingContext)
                 .Ignore();
 }
示例#16
0
        internal async Task Start(StatisticsProviderManager statsManager, IMessageCenter transport, GrainId clientId)
        {
            runtimeStats.Start();

            // Configure Metrics
            IProvider statsProvider = null;
            if (!string.IsNullOrEmpty(config.StatisticsProviderName))
            {
                var extType = config.StatisticsProviderName;
                statsProvider = statsManager.GetProvider(extType);
                var metricsDataPublisher = statsProvider as IClientMetricsDataPublisher;
                if (metricsDataPublisher == null)
                {
                    var msg = String.Format("Trying to create {0} as a metrics publisher, but the provider is not configured."
                        , extType);
                    throw new ArgumentException(msg, "ProviderType (configuration)");
                }
                var configurableMetricsDataPublisher = metricsDataPublisher as IConfigurableClientMetricsDataPublisher;
                if (configurableMetricsDataPublisher != null)
                {
                    configurableMetricsDataPublisher.AddConfiguration(
                        config.DeploymentId, config.DNSHostName, clientId.ToString(), transport.MyAddress.Endpoint.Address);
                }
                tableStatistics = new ClientTableStatistics(transport, metricsDataPublisher, runtimeStats)
                {
                    MetricsTableWriteInterval = config.StatisticsMetricsTableWriteInterval
                };
            }
            else if (config.UseAzureSystemStore)
            {
                // Hook up to publish client metrics to Azure storage table
                var publisher = AssemblyLoader.LoadAndCreateInstance<IClientMetricsDataPublisher>(Constants.ORLEANS_AZURE_UTILS_DLL, logger);
                await publisher.Init(config, transport.MyAddress.Endpoint.Address, clientId.ToParsableString());
                tableStatistics = new ClientTableStatistics(transport, publisher, runtimeStats)
                {
                    MetricsTableWriteInterval = config.StatisticsMetricsTableWriteInterval
                };
            }

            // Configure Statistics
            if (config.StatisticsWriteLogStatisticsToTable)
            {
                if (statsProvider != null)
                {
                    logStatistics.StatsTablePublisher = statsProvider as IStatisticsPublisher;
                    // Note: Provider has already been Init-ialized above.
                }
                else if (config.UseAzureSystemStore)
                {
                    var statsDataPublisher = AssemblyLoader.LoadAndCreateInstance<IStatisticsPublisher>(Constants.ORLEANS_AZURE_UTILS_DLL, logger);
                    await statsDataPublisher.Init(false, config.DataConnectionString, config.DeploymentId,
                        transport.MyAddress.Endpoint.ToString(), clientId.ToParsableString(), config.DNSHostName);
                    logStatistics.StatsTablePublisher = statsDataPublisher;
                }
            }
            logStatistics.Start();
        }
示例#17
0
 internal void ClientAdded(GrainId clientId)
 {
     // Use a ActivationId that is hashed from clientId, and not random ActivationId.
     // That way, when we refresh it in the directiry, it's the same one.
     var addr = GetClientActivationAddress(clientId);
     scheduler.QueueTask(
         () => ExecuteWithRetries(() => grainDirectory.RegisterAsync(addr), ErrorCode.ClientRegistrarFailedToRegister, String.Format("Directory.RegisterAsync {0} failed.", addr)), 
         this.SchedulingContext)
                 .Ignore();
 }
 internal List<ActivationAddress> GetHandedOffInfo(GrainId grain)
 {
     foreach (var partition in directoryPartitionsMap.Values)
     {
         var result = partition.LookUpGrain(grain);
         if (result.Addresses != null)
             return result.Addresses;
     }
     return null;
 }
        private Task<PlacementResult> MakePlacement(PlacementStrategy strategy, GrainId grain, IPlacementContext context, CachedLocalStat minLoadedSilo)
        {
            // Increment placement by number of silos instead of by one.
            // This is our trick to get more balanced placement, accounting to the probable
            // case when multiple silos place on the same silo at the same time, before stats are refreshed.
            minLoadedSilo.IncrementActivationCount(localCache.Count);

            return Task.FromResult(PlacementResult.SpecifyCreation(
                minLoadedSilo.Address,
                strategy,
                context.GetGrainTypeName(grain)));
        }
示例#20
0
 private void OnCollectActivation(GrainId grainId)
 {
     int other = grainId.GetTypeCode();
     int self = Data.Address.Grain.GetTypeCode();
     if (other == self)
     {
         IBusyActivationGcTestGrain1 g = GrainFactory.GetGrain<IBusyActivationGcTestGrain1>(grainId.GetPrimaryKey());
         for (int i = 0; i < burstCount; ++i)
         {
             g.Delay(TimeSpan.FromMilliseconds(10)).Ignore();
         }
     }         
 }
 internal List<ActivationAddress> GetHandedOffInfo(GrainId grain)
 {
     foreach (var partition in directoryPartitionsMap.Values)
     {
         var result = partition.LookUpGrain(grain);
         if (result != null)
         {
             // Force the list to be created in order to avoid race conditions
             return result.Item1.Select(pair => ActivationAddress.GetAddress(pair.Item1, grain, pair.Item2)).ToList();
         }
     }
     return null;
 }
示例#22
0
        /// <summary>
        /// Precedence function to resolve races among clusters that are trying to create an activation for a particular grain.
        /// </summary>
        /// <param name="grain">The GrainID under consideration.</param>
        /// <param name="clusterLeft"></param>
        /// <param name="clusterRight"></param>
        /// <returns>
        /// The function returns "true" if clusterLeft has precedence over clusterRight.
        /// </returns>
        internal static bool ActivationPrecedenceFunc(GrainId grain, string clusterLeft, string clusterRight)
        {
            // Make sure that we're not calling this function with default cluster identifiers.
            if (clusterLeft == null || clusterRight == null)
            {
                throw new OrleansException("ActivationPrecedenceFunction must be called with valid cluster identifiers.");
            }

            // use string comparison for cluster precedence, with polarity based on uniform grain hash
            if (grain.GetUniformHashCode() % 2 == 0)
                return string.Compare(clusterLeft, clusterRight, StringComparison.Ordinal) < 0;
            else
                return string.Compare(clusterRight, clusterLeft, StringComparison.Ordinal) < 0;
        }
 public ActivationAddress AddSingleActivation(GrainId grain, ActivationId act, SiloAddress silo, MultiClusterStatus registrationStatus = MultiClusterStatus.Owned)
 {
     SingleInstance = true;
     if (Instances.Count > 0)
     {
         var item = Instances.First();
         return ActivationAddress.GetAddress(item.Value.SiloAddress, grain, item.Key);
     }
     else
     {
         Instances.Add(act, new ActivationInfo(silo, registrationStatus));
         VersionTag = rand.Next();
         return ActivationAddress.GetAddress(silo, grain, act, registrationStatus);
     }
 }
示例#24
0
 public ActivationAddress AddSingleActivation(GrainId grain, ActivationId act, SiloAddress silo)
 {
     SingleInstance = true;
     if (Instances.Count > 0)
     {
         var item = Instances.First();
         return ActivationAddress.GetAddress(item.Value.SiloAddress, grain, item.Key);
     }
     else
     {
         Instances.Add(act, new ActivationInfo(silo));
         VersionTag = rand.Next();
         return ActivationAddress.GetAddress(silo, grain, act);
     }
 }
        internal PersistentStreamPullingManager(
            GrainId id, 
            string strProviderName, 
            IStreamProviderRuntime runtime,
            IStreamPubSub streamPubSub,
            IQueueAdapterFactory adapterFactory,
            IStreamQueueBalancer streamQueueBalancer,
            TimeSpan queueGetPeriod, 
            TimeSpan initQueueTimeout,
            TimeSpan maxEvenDeliveryTime)
            : base(id, runtime.ExecutingSiloAddress)
        {
            if (string.IsNullOrWhiteSpace(strProviderName))
            {
                throw new ArgumentNullException("strProviderName");
            }
            if (runtime == null)
            {
                throw new ArgumentNullException("runtime", "IStreamProviderRuntime runtime reference should not be null");
            }
            if (streamPubSub == null)
            {
                throw new ArgumentNullException("streamPubSub", "StreamPubSub reference should not be null");
            }
            if (streamQueueBalancer == null)
            {
                throw new ArgumentNullException("streamQueueBalancer", "IStreamQueueBalancer streamQueueBalancer reference should not be null");
            }

            queuesToAgentsMap = new Dictionary<QueueId, PersistentStreamPullingAgent>();
            streamProviderName = strProviderName;
            providerRuntime = runtime;
            pubSub = streamPubSub;
            this.queueGetPeriod = queueGetPeriod;
            this.initQueueTimeout = initQueueTimeout;
            this.maxEvenDeliveryTime = maxEvenDeliveryTime;
            nonReentrancyGuarantor = new AsyncSerialExecutor();
            latestRingNotificationSequenceNumber = 0;
            latestCommandNumber = 0;
            queueBalancer = streamQueueBalancer;
            this.adapterFactory = adapterFactory;

            queueAdapterCache = adapterFactory.GetQueueAdapterCache();
            logger = providerRuntime.GetLogger(GetType().Name + "-" + streamProviderName);
            logger.Info((int)ErrorCode.PersistentStreamPullingManager_01, "Created {0} for Stream Provider {1}.", GetType().Name, streamProviderName);

            IntValueStatistic.FindOrCreate(new StatisticName(StatisticNames.STREAMS_PERSISTENT_STREAM_NUM_PULLING_AGENTS, strProviderName), () => queuesToAgentsMap.Count);
        }
        internal PersistentStreamPullingManager(
            GrainId id, 
            string strProviderName, 
            IStreamProviderRuntime runtime,
            IStreamPubSub streamPubSub,
            IQueueAdapterFactory adapterFactory,
            IStreamQueueBalancer streamQueueBalancer,
            PersistentStreamProviderConfig config)
            : base(id, runtime.ExecutingSiloAddress)
        {
            if (string.IsNullOrWhiteSpace(strProviderName))
            {
                throw new ArgumentNullException("strProviderName");
            }
            if (runtime == null)
            {
                throw new ArgumentNullException("runtime", "IStreamProviderRuntime runtime reference should not be null");
            }
            if (streamPubSub == null)
            {
                throw new ArgumentNullException("streamPubSub", "StreamPubSub reference should not be null");
            }
            if (streamQueueBalancer == null)
            {
                throw new ArgumentNullException("streamQueueBalancer", "IStreamQueueBalancer streamQueueBalancer reference should not be null");
            }

            queuesToAgentsMap = new Dictionary<QueueId, PersistentStreamPullingAgent>();
            streamProviderName = strProviderName;
            providerRuntime = runtime;
            pubSub = streamPubSub;
            this.config = config;
            nonReentrancyGuarantor = new AsyncSerialExecutor();
            latestRingNotificationSequenceNumber = 0;
            latestCommandNumber = 0;
            queueBalancer = streamQueueBalancer;
            this.adapterFactory = adapterFactory;

            queueAdapterCache = adapterFactory.GetQueueAdapterCache();
            logger = TraceLogger.GetLogger(GetType().Name + "-" + streamProviderName, TraceLogger.LoggerType.Provider);
            Log(ErrorCode.PersistentStreamPullingManager_01, "Created {0} for Stream Provider {1}.", GetType().Name, streamProviderName);

            IntValueStatistic.FindOrCreate(new StatisticName(StatisticNames.STREAMS_PERSISTENT_STREAM_NUM_PULLING_AGENTS, strProviderName), () => queuesToAgentsMap.Count);
            queuePrintTimer = base.RegisterTimer(AsyncTimerCallback, null, QUEUES_PRINT_PERIOD, QUEUES_PRINT_PERIOD);
        }
示例#27
0
        internal override async Task<PlacementResult> OnSelectActivation(
            PlacementStrategy strategy, GrainId target, IPlacementContext context)
        {
            List<ActivationAddress> places = await context.Lookup(target);
            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 > 0
            // 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)]);
            if (places.Count > 0)
                return PlacementResult.IdentifySelection(places[random.Next(places.Count)]);
            // we return null to indicate that we were unable to select a target from places activations.
            return null;
        }
示例#28
0
        protected bool ReceiveSocketPreample(Socket sock, bool expectProxiedConnection, out GrainId client)
        {
            client = null;

            if (Cts.IsCancellationRequested)
            {
                return(false);
            }

            if (!ReadConnectionPreamble(sock, out client))
            {
                return(false);
            }

            if (Log.IsEnabled(LogLevel.Trace))
            {
                Log.Trace(ErrorCode.MessageAcceptor_Connection, "Received connection from {0} at source address {1}", client, sock.RemoteEndPoint.ToString());
            }

            if (expectProxiedConnection)
            {
                // Proxied Gateway Connection - must have sender id
                if (client.Equals(Constants.SiloDirectConnectionId))
                {
                    Log.Error(ErrorCode.MessageAcceptor_NotAProxiedConnection, $"Gateway received unexpected non-proxied connection from {client} at source address {sock.RemoteEndPoint}");
                    return(false);
                }
            }
            else
            {
                // Direct connection - should not have sender id
                if (!client.Equals(Constants.SiloDirectConnectionId))
                {
                    Log.Error(ErrorCode.MessageAcceptor_UnexpectedProxiedConnection, $"Silo received unexpected proxied connection from {client} at source address {sock.RemoteEndPoint}");
                    return(false);
                }
            }

            lock (Lockable)
            {
                OpenReceiveSockets.Add(sock);
            }

            return(true);
        }
示例#29
0
        /// <summary>
        /// Finds the silo that owns the directory information for the given grain ID.
        /// This routine will always return a non-null silo address unless the excludeThisSiloIfStopping parameter is true,
        /// this is the only silo known, and this silo is stopping.
        /// </summary>
        /// <param name="grain"></param>
        /// <param name="excludeThisSiloIfStopping"></param>
        /// <returns></returns>
        public SiloAddress CalculateTargetSilo(GrainId grain, bool excludeThisSiloIfStopping = true)
        {
            // give a special treatment for special grains
            if (grain.IsSystemTarget)
            {
                if (log.IsVerbose2)
                {
                    log.Verbose2("Silo {0} looked for a system target {1}, returned {2}", MyAddress, grain, MyAddress);
                }
                // every silo owns its system targets
                return(MyAddress);
            }

            if (Constants.SystemMembershipTableId.Equals(grain))
            {
                if (Seed == null)
                {
                    string grainName;
                    if (!Constants.TryGetSystemGrainName(grain, out grainName))
                    {
                        grainName = "MembershipTableGrain";
                    }

                    var errorMsg = grainName + " cannot run without Seed node - please check your silo configuration file and make sure it specifies a SeedNode element. " +
                                   " Alternatively, you may want to use AzureTable for LivenessType.";
                    throw new ArgumentException(errorMsg, "grain = " + grain);
                }
                // Directory info for the membership table grain has to be located on the primary (seed) node, for bootstrapping
                if (log.IsVerbose2)
                {
                    log.Verbose2("Silo {0} looked for a special grain {1}, returned {2}", MyAddress, grain, Seed);
                }
                return(Seed);
            }

            SiloAddress s;
            int         hash = unchecked ((int)grain.GetUniformHashCode());

            lock (membershipCache)
            {
                if (membershipRingList.Count == 0)
                {
                    // If the membership ring is empty, then we're the owner by default unless we're stopping.
                    return(excludeThisSiloIfStopping && !Running ? null : MyAddress);
                }

                // excludeMySelf from being a TargetSilo if we're not running and the excludeThisSIloIfStopping flag is true. see the comment in the Stop method.
                bool excludeMySelf = !Running && excludeThisSiloIfStopping;

                // need to implement a binary search, but for now simply traverse the list of silos sorted by their hashes
                s = membershipRingList.FindLast(siloAddr => (siloAddr.GetConsistentHashCode() <= hash) &&
                                                (!siloAddr.Equals(MyAddress) || !excludeMySelf));
                if (s == null)
                {
                    // If not found in the traversal, last silo will do (we are on a ring).
                    // We checked above to make sure that the list isn't empty, so this should always be safe.
                    s = membershipRingList[membershipRingList.Count - 1];
                    // Make sure it's not us...
                    if (s.Equals(MyAddress) && excludeMySelf)
                    {
                        s = membershipRingList.Count > 1 ? membershipRingList[membershipRingList.Count - 2] : null;
                    }
                }
            }
            if (log.IsVerbose2)
            {
                log.Verbose2("Silo {0} calculated directory partition owner silo {1} for grain {2}: {3} --> {4}", MyAddress, s, grain, hash, s.GetConsistentHashCode());
            }
            return(s);
        }
示例#30
0
 public Task <List <ActivationAddress> > Lookup(GrainId grainId) => GetGrainLocator(grainId).Lookup(grainId);
示例#31
0
        private async Task <GrainState <TestStoreGrainState> > Test_PersistenceProvider_WriteClearRead(string grainTypeName,
                                                                                                       IGrainStorage store, GrainState <TestStoreGrainState> grainState = null, GrainId grainId = null)
        {
            GrainReference reference = this.fixture.InternalGrainFactory.GetGrain(grainId ?? GrainId.NewId());

            if (grainState == null)
            {
                grainState = TestStoreGrainState.NewRandomState();
            }

            Stopwatch sw = new Stopwatch();

            sw.Start();

            await store.WriteStateAsync(grainTypeName, reference, grainState);

            TimeSpan writeTime = sw.Elapsed;

            sw.Restart();

            await store.ClearStateAsync(grainTypeName, reference, grainState);

            var storedGrainState = new GrainState <TestStoreGrainState>
            {
                State = new TestStoreGrainState()
            };
            await store.ReadStateAsync(grainTypeName, reference, storedGrainState);

            TimeSpan readTime = sw.Elapsed;

            this.output.WriteLine("{0} - Write time = {1} Read time = {2}", store.GetType().FullName, writeTime, readTime);
            Assert.NotNull(storedGrainState.State);
            Assert.Equal(default(string), storedGrainState.State.A);
            Assert.Equal(default(int), storedGrainState.State.B);
            Assert.Equal(default(long), storedGrainState.State.C);

            return(storedGrainState);
        }
示例#32
0
 public bool TryLocalLookup(GrainId grainId, out List <ActivationAddress> addresses) => GetGrainLocator(grainId).TryLocalLookup(grainId, out addresses);
示例#33
0
 private IGrainLocator GetGrainLocator(GrainId grainId)
 {
     return(!grainId.IsClient() && IsUsingCustomGrainLocator(grainId)
         ? (IGrainLocator)this.cachedGrainLocator
         : (IGrainLocator)this.dhtGrainLocator);
 }
示例#34
0
 /// <summary>
 /// 事务性事件提交
 /// 使用该函数前必须开启事务,不然会出现异常
 /// </summary>
 /// <param name="event"></param>
 /// <param name="uniqueId"></param>
 protected void TxRaiseEvent(IEvent @event, EventUID uniqueId = null)
 {
     if (Logger.IsEnabled(LogLevel.Trace))
     {
         Logger.LogTrace("Start transactionRaiseEvent, grain Id ={0} and state version = {1},event type = {2} ,event = {3},uniqueueId = {4}", GrainId.ToString(), Snapshot.Base.Version, @event.GetType().FullName, Serializer.SerializeToString(@event), uniqueId);
     }
     try
     {
         if (CurrentTransactionStartVersion == -1)
         {
             throw new UnopenedTransactionException(GrainId.ToString(), GrainType, nameof(TxRaiseEvent));
         }
         Snapshot.Base.IncrementDoingVersion(GrainType);//标记将要处理的Version
         var fullyEvent = new FullyEvent <PrimaryKey>
         {
             StateId = GrainId,
             Event   = @event,
             Base    = new EventBase
             {
                 Version = Snapshot.Base.Version + 1
             }
         };
         if (uniqueId == default)
         {
             uniqueId = EventUID.Empty;
         }
         if (string.IsNullOrEmpty(uniqueId.UID))
         {
             fullyEvent.Base.Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
         }
         else
         {
             fullyEvent.Base.Timestamp = uniqueId.Timestamp;
         }
         WaitingForTransactionTransports.Add(new EventTransport <PrimaryKey>(fullyEvent, uniqueId.UID, fullyEvent.StateId.ToString()));
         EventHandler.Apply(Snapshot, fullyEvent);
         Snapshot.Base.UpdateVersion(fullyEvent.Base, GrainType);//更新处理完成的Version
     }
     catch (Exception ex)
     {
         Logger.LogCritical(ex, "Grain Id = {0},event type = {1} and event = {2}", GrainId.ToString(), @event.GetType().FullName, Serializer.SerializeToString(@event));
         Snapshot.Base.DecrementDoingVersion();//还原doing Version
         throw;
     }
 }
示例#35
0
 public ActivationAddress ToAddress(GrainId grainId)
 {
     return ActivationAddress.GetAddress(Silo, grainId, Activation);
 }
 internal GrainDirectoryCacheEntry Get(GrainId key)
 {
     return(cache.Get(key));
 }
示例#37
0
 private IGrainDirectory GetGrainDirectory(GrainId grainId) => this.grainDirectoryResolver.Resolve(grainId);
        protected override async Task Run()
        {
            while (router.Running)
            {
                // Run through all cache entries and do the following:
                // 1. If the entry is not expired, skip it
                // 2. If the entry is expired and was not accessed in the last time interval -- throw it away
                // 3. If the entry is expired and was accessed in the last time interval, put into "fetch-batch-requests" list

                // At the end of the process, fetch batch requests for entries that need to be refreshed

                // Upon receiving refreshing answers, if the entry was not changed, double its expiration timer.
                // If it was changed, update the cache and reset the expiration timer.

                // this dictionary holds a map between a silo address and the list of grains that need to be refreshed
                var fetchInBatchList = new Dictionary <SiloAddress, List <GrainId> >();

                // get the list of cached grains


                // for debug only
                int cnt1 = 0, cnt2 = 0, cnt3 = 0, cnt4 = 0;

                // run through all cache entries
                var enumerator = cache.GetStoredEntries();
                while (enumerator.MoveNext())
                {
                    var     pair  = enumerator.Current;
                    GrainId grain = pair.Key;
                    var     entry = pair.Value;

                    SiloAddress owner = router.CalculateGrainDirectoryPartition(grain);
                    if (owner == null) // Null means there's no other silo and we're shutting down, so skip this entry
                    {
                        continue;
                    }

                    if (entry == null)
                    {
                        // 0. If the entry was deleted in parallel, presumably due to cleanup after silo death
                        cache.Remove(grain);            // for debug
                        cnt3++;
                    }
                    else if (!entry.IsExpired())
                    {
                        // 1. If the entry is not expired, skip it
                        cnt2++;                         // for debug
                    }
                    else if (entry.NumAccesses == 0)
                    {
                        // 2. If the entry is expired and was not accessed in the last time interval -- throw it away
                        cache.Remove(grain);            // for debug
                        cnt3++;
                    }
                    else
                    {
                        // 3. If the entry is expired and was accessed in the last time interval, put into "fetch-batch-requests" list
                        if (!fetchInBatchList.TryGetValue(owner, out var list))
                        {
                            fetchInBatchList[owner] = list = new List <GrainId>();
                        }
                        list.Add(grain);
                        // And reset the entry's access count for next time
                        entry.NumAccesses = 0;
                        cnt4++;                         // for debug
                    }
                }

                if (Log.IsEnabled(LogLevel.Trace))
                {
                    Log.Trace("Silo {0} self-owned (and removed) {1}, kept {2}, removed {3} and tries to refresh {4} grains", router.MyAddress, cnt1, cnt2, cnt3, cnt4);
                }

                // send batch requests
                SendBatchCacheRefreshRequests(fetchInBatchList);

                ProduceStats();

                // recheck every X seconds (Consider making it a configurable parameter)
                await Task.Delay(SLEEP_TIME_BETWEEN_REFRESHES);
            }
        }
        public bool Remove(GrainId key)
        {
            TValue tmp;

            return(cache.RemoveKey(key, out tmp));
        }
示例#40
0
        internal void UpdateClientId(GrainId clientId)
        {
            if (ClientId.Category != UniqueKey.Category.Client)
                throw new InvalidOperationException("Only handshake client ID can be updated with a cluster ID.");

            if (clientId.Category != UniqueKey.Category.GeoClient)
                throw new ArgumentException("Handshake client ID can only be updated  with a geo client.", nameof(clientId));

            ClientId = clientId;
        }
示例#41
0
        public async Task <List <ActivationAddress> > FullLookup(GrainId grain)
        {
            fullLookups.Increment();

            SiloAddress silo = CalculateTargetSilo(grain, false);

            // No need to check that silo != null since we're passing excludeThisSiloIfStopping = false

            if (log.IsVerbose)
            {
                log.Verbose("Silo {0} fully lookups for {1}-->{2} ({3}-->{4})", MyAddress, grain, silo, grain.GetUniformHashCode(), silo.GetConsistentHashCode());
            }

            // We assyme that getting here means the grain was not found locally (i.e., in TryFullLookup()).
            // We still check if we own the grain locally to avoid races between the time TryFullLookup() and FullLookup() were called.
            if (silo.Equals(MyAddress))
            {
                LocalDirectoryLookups.Increment();
                var localResult = DirectoryPartition.LookUpGrain(grain);
                if (localResult == null)
                {
                    // it can happen that we cannot find the grain in our partition if there were
                    // some recent changes in the membership
                    if (log.IsVerbose2)
                    {
                        log.Verbose2("FullLookup mine {0}=none", grain);
                    }
                    return(new List <ActivationAddress>());
                }
                var a = localResult.Item1.Select(t => ActivationAddress.GetAddress(t.Item1, grain, t.Item2)).Where(addr => IsValidSilo(addr.Silo)).ToList();
                if (log.IsVerbose2)
                {
                    log.Verbose2("FullLookup mine {0}={1}", grain, a.ToStrings());
                }
                LocalDirectorySuccesses.Increment();
                return(a);
            }

            // Just a optimization. Why sending a message to someone we know is not valid.
            if (!IsValidSilo(silo))
            {
                throw new OrleansException(String.Format("Current directory at {0} is not stable to perform the lookup for grain {1} (it maps to {2}, which is not a valid silo). Retry later.", MyAddress, grain, silo));
            }

            RemoteLookupsSent.Increment();
            Tuple <List <Tuple <SiloAddress, ActivationId> >, int> result = await GetDirectoryReference(silo).LookUp(grain, NUM_RETRIES);

            // update the cache
            List <Tuple <SiloAddress, ActivationId> > entries = result.Item1.Where(t => IsValidSilo(t.Item1)).ToList();
            List <ActivationAddress> addresses = entries.Select(t => ActivationAddress.GetAddress(t.Item1, grain, t.Item2)).ToList();

            if (log.IsVerbose2)
            {
                log.Verbose2("FullLookup remote {0}={1}", grain, addresses.ToStrings());
            }

            if (entries.Count > 0)
            {
                DirectoryCache.AddOrUpdate(grain, entries, result.Item2);
            }

            return(addresses);
        }
示例#42
0
 internal void Write(GrainId id)
 {
     Write(id.Key);
 }
示例#43
0
 private bool IsUsingCustomGrainLocator(GrainId grainId) => this.grainDirectoryResolver.Resolve(grainId) != default;
 public void Delete(GrainId gid)
 {
     throw new InvalidOperationException();
 }
示例#45
0
        public async Task RollbackTransaction(long transactionId)
        {
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace("Start rollback transaction with id = {0},event counts = {1}, from version {2} to version {3}", GrainId.ToString(), WaitingForTransactionTransports.Count.ToString(), CurrentTransactionStartVersion.ToString(), Snapshot.Base.Version.ToString());
            }
            if (CurrentTransactionId == transactionId && CurrentTransactionStartVersion != -1 && Snapshot.Base.Version >= CurrentTransactionStartVersion)
            {
                try
                {
                    if (BackupSnapshot.Base.Version == CurrentTransactionStartVersion - 1)
                    {
                        Snapshot = new Snapshot <PrimaryKey, StateType>(GrainId)
                        {
                            Base  = BackupSnapshot.Base.Clone(),
                            State = BackupSnapshot.State.Clone()
                        };
                    }
                    else
                    {
                        if (BackupSnapshot.Base.Version >= CurrentTransactionStartVersion)
                        {
                            await EventStorage.DeleteEnd(Snapshot.Base.StateId, CurrentTransactionStartVersion, Snapshot.Base.LatestMinEventTimestamp);
                        }
                        await RecoverySnapshot();
                    }

                    WaitingForTransactionTransports.Clear();
                    RestoreTransactionTemporaryState();
                    TransactionSemaphore.Release();
                    if (Logger.IsEnabled(LogLevel.Trace))
                    {
                        Logger.LogTrace("Rollback transaction successfully with id = {0},state version = {1}", GrainId.ToString(), Snapshot.Base.Version.ToString());
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogCritical(ex, "Rollback transaction failed with Id = {1}", GrainId.ToString());
                    throw;
                }
            }
        }
示例#46
0
 public static PlacementStrategy GetGrainPlacementStrategy(this IPlacementContext @this, GrainId grainId, string genericArguments = null)
 {
     return(@this.GetGrainPlacementStrategy(grainId.GetTypeCode(), genericArguments));
 }
示例#47
0
 public async Task CommitTransaction(long transactionId)
 {
     if (Logger.IsEnabled(LogLevel.Trace))
     {
         Logger.LogTrace("Commit transaction with id = {0},event counts = {1}, from version {2} to version {3}", GrainId.ToString(), WaitingForTransactionTransports.Count.ToString(), CurrentTransactionStartVersion.ToString(), Snapshot.Base.Version.ToString());
     }
     if (WaitingForTransactionTransports.Count > 0)
     {
         if (CurrentTransactionId != transactionId)
         {
             throw new TxCommitException();
         }
         try
         {
             var onCommitTask = OnCommitTransaction(transactionId);
             if (!onCommitTask.IsCompletedSuccessfully)
             {
                 await onCommitTask;
             }
             foreach (var transport in WaitingForTransactionTransports)
             {
                 var startTask = OnRaiseStart(transport.FullyEvent);
                 if (!startTask.IsCompletedSuccessfully)
                 {
                     await startTask;
                 }
                 transport.BytesTransport = new EventBytesTransport(
                     TypeContainer.GetTypeCode(transport.FullyEvent.Event.GetType()),
                     GrainId,
                     transport.FullyEvent.Base.GetBytes(),
                     Serializer.SerializeToBytes(transport.FullyEvent.Event)
                     );
             }
             await EventStorage.TransactionBatchAppend(WaitingForTransactionTransports);
         }
         catch (Exception ex)
         {
             Logger.LogError(ex, "Commit transaction failed, grain Id = {1}", GrainId.ToString());
             throw;
         }
     }
 }
示例#48
0
        public static Task <List <ActivationAddress> > Lookup(this IPlacementContext @this, GrainId grainId)
        {
            List <ActivationAddress> l;

            return(@this.FastLookup(grainId, out l) ? Task.FromResult(l) : @this.FullLookup(grainId));
        }
示例#49
0
        protected async Task BeginTransaction(long transactionId)
        {
            if (Logger.IsEnabled(LogLevel.Trace))
            {
                Logger.LogTrace("Begin transaction with grainid {0} and transactionId {1},transaction start state version {2}", GrainId.ToString(), transactionId, CurrentTransactionStartVersion.ToString());
            }
            if (TransactionStartMilliseconds != 0 &&
                DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - TransactionStartMilliseconds > CoreOptions.TransactionMillisecondsTimeout)
            {
                if (await _transactionTimeoutLock.WaitAsync(CoreOptions.TransactionMillisecondsTimeout))
                {
                    try
                    {
                        if (TransactionStartMilliseconds != 0 &&
                            DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - TransactionStartMilliseconds > CoreOptions.TransactionMillisecondsTimeout)
                        {
                            await RollbackTransaction(CurrentTransactionId);//事务超时自动回滚

                            Logger.LogError("Transaction timeout, automatic rollback,grain id = {1}", GrainId.ToString());
                        }
                    }
                    finally
                    {
                        _transactionTimeoutLock.Release();
                    }
                }
            }
            if (await TransactionSemaphore.WaitAsync(CoreOptions.TransactionMillisecondsTimeout))
            {
                try
                {
                    SnapshotCheck();
                    CurrentTransactionStartVersion = Snapshot.Base.Version + 1;
                    CurrentTransactionId           = transactionId;
                    TransactionStartMilliseconds   = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                }
                catch
                {
                    TransactionSemaphore.Release();
                    throw;
                }
            }
            else
            {
                throw new BeginTxTimeoutException(GrainId.ToString(), transactionId, GrainType);
            }
        }
        public bool Remove(GrainId key)
        {
            GrainDirectoryCacheEntry tmp;

            return(cache.RemoveKey(key, out tmp));
        }
示例#51
0
        private async Task Test_PersistenceProvider_Read(string grainTypeName, IGrainStorage store,
                                                         GrainState <TestStoreGrainState> grainState = null, GrainId grainId = null)
        {
            var reference = this.fixture.InternalGrainFactory.GetGrain(grainId ?? GrainId.NewId());

            if (grainState == null)
            {
                grainState = new GrainState <TestStoreGrainState>(new TestStoreGrainState());
            }
            var storedGrainState = new GrainState <TestStoreGrainState>(new TestStoreGrainState());

            Stopwatch sw = new Stopwatch();

            sw.Start();

            await store.ReadStateAsync(grainTypeName, reference, storedGrainState);

            TimeSpan readTime = sw.Elapsed;

            this.output.WriteLine("{0} - Read time = {1}", store.GetType().FullName, readTime);

            var storedState = storedGrainState.State;

            Assert.Equal(grainState.State.A, storedState.A);
            Assert.Equal(grainState.State.B, storedState.B);
            Assert.Equal(grainState.State.C, storedState.C);
        }
示例#52
0
        /// <summary>
        /// For testing purposes only.
        /// Returns the silos that this silo thinks hold copies of the directory information for
        /// the provided grain ID.
        /// </summary>
        /// <param name="grain"></param>
        /// <returns></returns>
        public List <SiloAddress> GetSilosHoldingDirectoryInformationForGrain(GrainId grain)
        {
            var primary = CalculateTargetSilo(grain);

            return(FindPredecessors(primary, 1));
        }
 public bool LookUp(GrainId key, out TValue result)
 {
     return(cache.TryGetValue(key, out result));
 }
示例#54
0
        public OutsideRuntimeClient(ClientConfiguration cfg, GrainFactory grainFactory, bool secondary = false)
        {
            this.grainFactory = grainFactory;
            this.clientId     = GrainId.NewClientId();

            if (cfg == null)
            {
                Console.WriteLine("An attempt to create an OutsideRuntimeClient with null ClientConfiguration object.");
                throw new ArgumentException("OutsideRuntimeClient was attempted to be created with null ClientConfiguration object.", "cfg");
            }

            this.config = cfg;

            if (!LogManager.IsInitialized)
            {
                LogManager.Initialize(config);
            }
            StatisticsCollector.Initialize(config);
            SerializationManager.Initialize(config.UseStandardSerializer, cfg.SerializationProviders, config.UseJsonFallbackSerializer);
            logger    = LogManager.GetLogger("OutsideRuntimeClient", LoggerType.Runtime);
            appLogger = LogManager.GetLogger("Application", LoggerType.Application);

            try
            {
                LoadAdditionalAssemblies();

                PlacementStrategy.Initialize();

                callbacks    = new ConcurrentDictionary <CorrelationId, CallbackData>();
                localObjects = new ConcurrentDictionary <GuidId, LocalObjectData>();

                if (!secondary)
                {
                    UnobservedExceptionsHandlerClass.SetUnobservedExceptionHandler(UnhandledException);
                }
                AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload;

                // Ensure SerializationManager static constructor is called before AssemblyLoad event is invoked
                SerializationManager.GetDeserializer(typeof(String));

                clientProviderRuntime     = new ClientProviderRuntime(grainFactory, new DefaultServiceProvider());
                statisticsProviderManager = new StatisticsProviderManager("Statistics", clientProviderRuntime);
                var statsProviderName = statisticsProviderManager.LoadProvider(config.ProviderConfigurations)
                                        .WaitForResultWithThrow(initTimeout);
                if (statsProviderName != null)
                {
                    config.StatisticsProviderName = statsProviderName;
                }

                responseTimeout = Debugger.IsAttached ? Constants.DEFAULT_RESPONSE_TIMEOUT : config.ResponseTimeout;
                BufferPool.InitGlobalBufferPool(config);
                var localAddress = ClusterConfiguration.GetLocalIPAddress(config.PreferredFamily, config.NetInterface);

                // Client init / sign-on message
                logger.Info(ErrorCode.ClientInitializing, string.Format(
                                "{0} Initializing OutsideRuntimeClient on {1} at {2} Client Id = {3} {0}",
                                BARS, config.DNSHostName, localAddress, clientId));
                string startMsg = string.Format("{0} Starting OutsideRuntimeClient with runtime Version='{1}' in AppDomain={2}",
                                                BARS, RuntimeVersion.Current, PrintAppDomainDetails());
                startMsg = string.Format("{0} Config= " + Environment.NewLine + " {1}", startMsg, config);
                logger.Info(ErrorCode.ClientStarting, startMsg);

                if (TestOnlyThrowExceptionDuringInit)
                {
                    throw new InvalidOperationException("TestOnlyThrowExceptionDuringInit");
                }

                config.CheckGatewayProviderSettings();

                var generation          = -SiloAddress.AllocateNewGeneration(); // Client generations are negative
                var gatewayListProvider = GatewayProviderFactory.CreateGatewayListProvider(config)
                                          .WithTimeout(initTimeout).Result;
                transport = new ProxiedMessageCenter(config, localAddress, generation, clientId, gatewayListProvider);

                if (StatisticsCollector.CollectThreadTimeTrackingStats)
                {
                    incomingMessagesThreadTimeTracking = new ThreadTrackingStatistic("ClientReceiver");
                }
            }
            catch (Exception exc)
            {
                if (logger != null)
                {
                    logger.Error(ErrorCode.Runtime_Error_100319, "OutsideRuntimeClient constructor failed.", exc);
                }
                ConstructorReset();
                throw;
            }
        }
示例#55
0
 public static void GetGrainTypeInfo(this IPlacementContext @this, GrainId grainId, out string grainClass, out PlacementStrategy placement, string genericArguments = null)
 {
     @this.GetGrainTypeInfo(grainId.GetTypeCode(), out grainClass, out placement, genericArguments);
 }
示例#56
0
 public static string GetGrainTypeName(this IPlacementContext @this, GrainId grainId, string genericArguments = null)
 {
     return(@this.GetGrainTypeName(grainId.GetTypeCode(), genericArguments));
 }
示例#57
0
 /// <summary>
 /// For testing purposes only.
 /// Returns the silo that this silo thinks is the primary owner of directory information for
 /// the provided grain ID.
 /// </summary>
 /// <param name="grain"></param>
 /// <returns></returns>
 public SiloAddress GetPrimaryForGrain(GrainId grain)
 {
     return(CalculateTargetSilo(grain));
 }
示例#58
0
        private void RunClientMessagePump(CancellationToken ct)
        {
            if (StatisticsCollector.CollectThreadTimeTrackingStats)
            {
                incomingMessagesThreadTimeTracking.OnStartExecution();
            }
            while (listenForMessages)
            {
                var message = transport.WaitMessage(Message.Categories.Application, ct);

                if (message == null) // if wait was cancelled
                {
                    break;
                }
#if TRACK_DETAILED_STATS
                if (StatisticsCollector.CollectThreadTimeTrackingStats)
                {
                    incomingMessagesThreadTimeTracking.OnStartProcessing();
                }
#endif

                // when we receive the first message, we update the
                // clientId for this client because it may have been modified to
                // include the cluster name
                if (!firstMessageReceived)
                {
                    firstMessageReceived = true;
                    if (!handshakeClientId.Equals(message.TargetGrain))
                    {
                        clientId = message.TargetGrain;
                        transport.UpdateClientId(clientId);
                        CurrentActivationAddress = ActivationAddress.GetAddress(transport.MyAddress, clientId, CurrentActivationAddress.Activation);
                    }
                    else
                    {
                        clientId = handshakeClientId;
                    }
                }

                switch (message.Direction)
                {
                case Message.Directions.Response:
                {
                    ReceiveResponse(message);
                    break;
                }

                case Message.Directions.OneWay:
                case Message.Directions.Request:
                {
                    this.DispatchToLocalObject(message);
                    break;
                }

                default:
                    logger.Error(ErrorCode.Runtime_Error_100327, String.Format("Message not supported: {0}.", message));
                    break;
                }
#if TRACK_DETAILED_STATS
                if (StatisticsCollector.CollectThreadTimeTrackingStats)
                {
                    incomingMessagesThreadTimeTracking.OnStopProcessing();
                    incomingMessagesThreadTimeTracking.IncrementNumberOfProcessed();
                }
#endif
            }
            if (StatisticsCollector.CollectThreadTimeTrackingStats)
            {
                incomingMessagesThreadTimeTracking.OnStopExecution();
            }
        }
示例#59
0
        public OutsideRuntimeClient(ClientConfiguration cfg, GrainFactory grainFactory, bool secondary = false)
        {
            this.grainFactory = grainFactory;
            this.clientId = GrainId.NewClientId();

            if (cfg == null)
            {
                Console.WriteLine("An attempt to create an OutsideRuntimeClient with null ClientConfiguration object.");
                throw new ArgumentException("OutsideRuntimeClient was attempted to be created with null ClientConfiguration object.", "cfg");
            }

            this.config = cfg;

            if (!TraceLogger.IsInitialized) TraceLogger.Initialize(config);
            StatisticsCollector.Initialize(config);
            SerializationManager.Initialize(config.UseStandardSerializer, cfg.SerializationProviders, config.UseJsonFallbackSerializer);
            logger = TraceLogger.GetLogger("OutsideRuntimeClient", TraceLogger.LoggerType.Runtime);
            appLogger = TraceLogger.GetLogger("Application", TraceLogger.LoggerType.Application);

            try
            {
                LoadAdditionalAssemblies();
                
                PlacementStrategy.Initialize();

                callbacks = new ConcurrentDictionary<CorrelationId, CallbackData>();
                localObjects = new ConcurrentDictionary<GuidId, LocalObjectData>();

                if (!secondary)
                {
                    UnobservedExceptionsHandlerClass.SetUnobservedExceptionHandler(UnhandledException);
                }
                // Ensure SerializationManager static constructor is called before AssemblyLoad event is invoked
                SerializationManager.GetDeserializer(typeof(String));

                clientProviderRuntime = new ClientProviderRuntime(grainFactory, new DefaultServiceProvider());
                statisticsProviderManager = new StatisticsProviderManager("Statistics", clientProviderRuntime);
                var statsProviderName = statisticsProviderManager.LoadProvider(config.ProviderConfigurations)
                    .WaitForResultWithThrow(initTimeout);
                if (statsProviderName != null)
                {
                    config.StatisticsProviderName = statsProviderName;
                }

                responseTimeout = Debugger.IsAttached ? Constants.DEFAULT_RESPONSE_TIMEOUT : config.ResponseTimeout;
                BufferPool.InitGlobalBufferPool(config);
                var localAddress = ClusterConfiguration.GetLocalIPAddress(config.PreferredFamily, config.NetInterface);

                // Client init / sign-on message
                logger.Info(ErrorCode.ClientInitializing, string.Format(
                    "{0} Initializing OutsideRuntimeClient on {1} at {2} Client Id = {3} {0}",
                    BARS, config.DNSHostName, localAddress, clientId));
                string startMsg = string.Format("{0} Starting OutsideRuntimeClient with runtime Version='{1}'", BARS, RuntimeVersion.Current);
                startMsg = string.Format("{0} Config= "  + Environment.NewLine + " {1}", startMsg, config);
                logger.Info(ErrorCode.ClientStarting, startMsg);

                if (TestOnlyThrowExceptionDuringInit)
                {
                    throw new Exception("TestOnlyThrowExceptionDuringInit");
                }

                config.CheckGatewayProviderSettings();

                var generation = -SiloAddress.AllocateNewGeneration(); // Client generations are negative
                var gatewayListProvider = GatewayProviderFactory.CreateGatewayListProvider(config)
                    .WithTimeout(initTimeout).Result;
                transport = new ProxiedMessageCenter(config, localAddress, generation, clientId, gatewayListProvider);
                
                if (StatisticsCollector.CollectThreadTimeTrackingStats)
                {
                    incomingMessagesThreadTimeTracking = new ThreadTrackingStatistic("ClientReceiver");
                }
            }
            catch (Exception exc)
            {
                if (logger != null) logger.Error(ErrorCode.Runtime_Error_100319, "OutsideRuntimeClient constructor failed.", exc);
                ConstructorReset();
                throw;
            }
        }
 public void AddOrUpdate(GrainId key, TValue value, int version)
 {
     // ignore the version number
     cache.Add(key, value);
 }