Example #1
0
        /// <summary>
        /// Called to start communication with the service.
        /// </summary>
        /// <param name="cancellationToken">CancellationToken instance.</param>
        /// <returns>String containing the URI the service will be listening on.</returns>
        public Task <string> OpenAsync(CancellationToken cancellationToken)
        {
            // Set the maximum number of concurrent connections.
            // Recommendation is from http://support.microsoft.com/kb/821268.
            System.Net.ServicePointManager.DefaultConnectionLimit = 12 * Environment.ProcessorCount;

            EndpointResourceDescription serviceEndpoint = _context.CodePackageActivationContext.GetEndpoint("OwinServiceEndpoint");
            int    port     = serviceEndpoint.Port;
            string protocol = Enum.GetName(typeof(EndpointProtocol), serviceEndpoint.Protocol).ToLowerInvariant();

            if (_context is StatefulServiceContext)
            {
                StatefulServiceContext ssc = (StatefulServiceContext)_context;

                _listeningAddress = String.Format(
                    CultureInfo.InvariantCulture,
                    "{0}://+:{1}/{2}/{3}/{4}/{5}",
                    protocol,
                    port,
                    _appRoot,
                    ssc.PartitionId,
                    ssc.ReplicaId,
                    Guid.NewGuid());
            }
            else if (_context is StatelessServiceContext)
            {
                _listeningAddress = String.Format(CultureInfo.InvariantCulture, "{0}://+:{1}/{2}", protocol, port, _appRoot);
            }
            else
            {
                _eventSource.ServiceRequestFailed(_context.ServiceTypeName, _context.PartitionId, _context.ReplicaOrInstanceId, nameof(OpenAsync), $"Unknown ServiceContext type '{_context.GetType().FullName}' in service type '{_context.ServiceTypeName}'.");
                throw new InvalidOperationException();
            }

            _publishAddress = this._listeningAddress.Replace("+", FabricRuntime.GetNodeContext().IPAddressOrFQDN);

            try
            {
                _eventSource.CreateCommunicationListener(_context.ServiceTypeName, _context.PartitionId, _context.ReplicaOrInstanceId, _listeningAddress);
                _serverHandle = WebApp.Start(_listeningAddress, StartupConfiguration);
                return(Task.FromResult(_publishAddress));
            }
            catch (Exception ex)
            {
                _eventSource.ServiceRequestFailed(_context.ServiceTypeName, _context.PartitionId, _context.ReplicaOrInstanceId, nameof(OpenAsync), ex.ToString());
                this.StopWebServer();
                throw;
            }
        }
Example #2
0
        /// <summary>
        /// Reports the health of a node.
        /// </summary>
        /// <param name="ttl"></param>
        public async Task ReportNodeHealthAndLoadAsync(TimeSpan ttl)
        {
            const int         MB  = 1048576;
            HealthInformation hi  = null;
            NodeHealthReport  nhr = null;

            try
            {
                // Get the global memory load and report as a node health parameter.
                NativeMethods.MEMORYSTATUSEX msex = new NativeMethods.MEMORYSTATUSEX();
                if (NativeMethods.GlobalMemoryStatus(ref msex))
                {
                    HealthState hs = (msex.dwMemoryLoad > 80) ? HealthState.Warning : (msex.dwMemoryLoad > 95) ? HealthState.Error : HealthState.Ok;

                    // Save the current memory load.
                    MemoryLoad = msex.dwMemoryLoad;

                    // Create the health information to report to Service Fabric.
                    hi                   = new HealthInformation("NodeHealth", "MemoryLoad", hs);
                    hi.TimeToLive        = (0.0 <= ttl.TotalMilliseconds) ? TimeSpan.FromSeconds(30) : ttl;
                    hi.Description       = $"Percent of memory in used on this node: {msex.dwMemoryLoad}";
                    hi.RemoveWhenExpired = true;
                    hi.SequenceNumber    = HealthInformation.AutoSequenceNumber;

                    // Create a replica health report.
                    nhr = new NodeHealthReport(Context.NodeContext.NodeName, hi);
                    ServiceFabricClient.HealthManager.ReportHealth(nhr);
                }

                // Create the health information and send report to Service Fabric.
                hi                   = new HealthInformation("NodeHealth", "CPU", HealthState.Ok);
                hi.TimeToLive        = (0.0 <= ttl.TotalMilliseconds) ? TimeSpan.FromSeconds(30) : ttl;
                hi.Description       = $"Total CPU usage on this node: {_cpuCounter.NextValue()}";
                hi.RemoveWhenExpired = true;
                hi.SequenceNumber    = HealthInformation.AutoSequenceNumber;
                nhr                  = new NodeHealthReport(Context.NodeContext.NodeName, hi);
                ServiceFabricClient.HealthManager.ReportHealth(nhr);

                // Get the number of deployed replicas on this node for this service.
                int serviceReplicaCount = 0;
                var replicaList         = await ServiceFabricClient.QueryManager.GetDeployedReplicaListAsync(Context.NodeContext.NodeName, Application);

                for (int i = 0; i < replicaList.Count; i++)
                {
                    if (Context.ServiceName == replicaList[i].ServiceName)
                    {
                        serviceReplicaCount++;
                    }
                }

                DateTimeOffset oldSampleTime = _timeOfCpuSample;
                TimeSpan       oldCpuSample  = _cpuProcessTime;
                _cpuProcessTime  = Process.GetCurrentProcess().TotalProcessorTime;
                _timeOfCpuSample = DateTimeOffset.UtcNow;

                long processTicks        = (_cpuProcessTime - oldCpuSample).Ticks;
                long periodTicks         = (_timeOfCpuSample - oldSampleTime).Ticks;
                long cpuTicks            = (processTicks / periodTicks);
                long cpuPercent          = (cpuTicks / serviceReplicaCount) * 100;
                long partitionWorkingSet = ((Process.GetCurrentProcess().WorkingSet64 / MB) / serviceReplicaCount);

                // Report the partition load metrics.
                LoadMetric[] metrics = new LoadMetric[]
                {
                    new LoadMetric("PartitionCPU", (int)cpuPercent),
                    new LoadMetric("WorkingSetMB", Convert.ToInt32(partitionWorkingSet))
                };

                ReportLoad(metrics);
            }
            catch (Exception ex)
            {
                _eventSource.ServiceRequestFailed(Context.ServiceTypeName, Context.PartitionId, Context.ReplicaId, "ReportNodeHealthAndLoadAsync", ex.Message);
            }
        }