public async Task <IHttpActionResult> Post([FromUri] int countyId, [FromBody] CountyStatsViewModel status)
        {
            IReliableDictionary <int, NationalCountyStats> dictionary =
                await this.stateManager.GetOrAddAsync <IReliableDictionary <int, NationalCountyStats> >(HealthStatusDictionary);

            using (ITransaction tx = this.stateManager.CreateTransaction())
            {
                await dictionary.SetAsync(
                    tx,
                    countyId,
                    new NationalCountyStats(
                        status.DoctorCount,
                        status.PatientCount,
                        status.HealthReportCount,
                        status.AverageHealthIndex));

                await tx.CommitAsync();
            }

            ServiceEventSource.Current.Message("National Service recieved and saved report {0}|{1}", countyId, status);
            return(this.Ok());
        }
Beispiel #2
0
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            ConfigurationPackage configPackage = this.Context.CodePackageActivationContext.GetConfigurationPackageObject("Config");

            this.UpdateConfigSettings(configPackage.Settings);

            this.Context.CodePackageActivationContext.ConfigurationPackageModifiedEvent
                += this.CodePackageActivationContext_ConfigurationPackageModifiedEvent;

            this.indexCalculator = new HealthIndexCalculator(this.Context);

            ServicePrimer primer = new ServicePrimer();
            await primer.WaitForStatefulService(this.nationalServiceInstanceUri);

            IReliableDictionary <int, string> countyNamesDictionary =
                await this.StateManager.GetOrAddAsync <IReliableDictionary <int, string> >(CountyNameDictionaryName);

            ServiceEventSource.Current.ServiceMessage(this, "CountyService starting data processing.");
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    //every ten seconds, grab the counties and send them to national
                    await Task.Delay(this.interval, cancellationToken);

                    ServicePartitionClient <HttpCommunicationClient> servicePartitionClient =
                        new ServicePartitionClient <HttpCommunicationClient>(
                            this.clientFactory,
                            this.nationalServiceInstanceUri);

                    IList <KeyValuePair <int, string> > countyNames = new List <KeyValuePair <int, string> >();

                    using (ITransaction tx = this.StateManager.CreateTransaction())
                    {
                        IAsyncEnumerator <KeyValuePair <int, string> > enumerator = (await countyNamesDictionary.CreateEnumerableAsync(tx)).GetAsyncEnumerator();

                        while (await enumerator.MoveNextAsync(cancellationToken))
                        {
                            countyNames.Add(enumerator.Current);
                        }
                    }

                    foreach (KeyValuePair <int, string> county in countyNames)
                    {
                        IReliableDictionary <Guid, CountyDoctorStats> countyHealth =
                            await
                            this.StateManager.GetOrAddAsync <IReliableDictionary <Guid, CountyDoctorStats> >(
                                string.Format(CountyHealthDictionaryName, county.Key));

                        int totalDoctorCount       = 0;
                        int totalPatientCount      = 0;
                        int totalHealthReportCount = 0;
                        int avgHealth = 0;

                        using (ITransaction tx = this.StateManager.CreateTransaction())
                        {
                            IAsyncEnumerable <KeyValuePair <Guid, CountyDoctorStats> > healthRecords = await countyHealth.CreateEnumerableAsync(tx);

                            IAsyncEnumerator <KeyValuePair <Guid, CountyDoctorStats> > enumerator = healthRecords.GetAsyncEnumerator();

                            IList <KeyValuePair <Guid, CountyDoctorStats> > records = new List <KeyValuePair <Guid, CountyDoctorStats> >();

                            while (await enumerator.MoveNextAsync(cancellationToken))
                            {
                                records.Add(enumerator.Current);
                            }

                            avgHealth = this.indexCalculator.ComputeAverageIndex(records.Select(x => x.Value.AverageHealthIndex));

                            foreach (KeyValuePair <Guid, CountyDoctorStats> item in records)
                            {
                                totalDoctorCount++;
                                totalPatientCount      += item.Value.PatientCount;
                                totalHealthReportCount += item.Value.HealthReportCount;
                            }
                        }

                        CountyStatsViewModel payload = new CountyStatsViewModel(totalDoctorCount, totalPatientCount, totalHealthReportCount, avgHealth);

                        await servicePartitionClient.InvokeWithRetryAsync(
                            client =>
                        {
                            Uri serviceAddress = new Uri(client.BaseAddress, string.Format("national/health/{0}", county.Key));

                            HttpWebRequest request   = WebRequest.CreateHttp(serviceAddress);
                            request.Method           = "POST";
                            request.ContentType      = "application/json";
                            request.Timeout          = (int)client.OperationTimeout.TotalMilliseconds;
                            request.ReadWriteTimeout = (int)client.ReadWriteTimeout.TotalMilliseconds;

                            using (Stream requestStream = request.GetRequestStream())
                            {
                                using (BufferedStream buffer = new BufferedStream(requestStream))
                                {
                                    using (StreamWriter writer = new StreamWriter(buffer))
                                    {
                                        JsonSerializer serializer = new JsonSerializer();
                                        serializer.Serialize(writer, payload);
                                        buffer.Flush();
                                    }

                                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                                    {
                                        ServiceEventSource.Current.ServiceMessage(this, "County Data Sent {0}", serviceAddress);
                                        return(Task.FromResult(true));
                                    }
                                }
                            }
                        },
                            cancellationToken);
                    }
                }
                catch (TaskCanceledException)
                {
                    throw;
                }
                catch (Exception exception)
                {
                    ServiceEventSource.Current.ServiceMessage(
                        this,
                        "CountyService encountered an exception trying to send data to National Service: {0}",
                        exception.ToString());
                    continue;
                }
            }
        }
Beispiel #3
0
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            ServiceEventSource.Current.ServiceMessage(this.Context, "CountyService starting data processing.");

            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    //every interval seconds, grab the counties and send them to national
                    await Task.Delay(TimeSpan.FromSeconds(int.Parse(this.GetSetting("UpdateFrequency"))), cancellationToken);

                    IReliableDictionary <int, string> countyNamesDictionary =
                        await this.StateManager.GetOrAddAsync <IReliableDictionary <int, string> >(CountyNameDictionaryName);

                    IList <KeyValuePair <int, string> > countyNames = new List <KeyValuePair <int, string> >();

                    using (ITransaction tx = this.StateManager.CreateTransaction())
                    {
                        var enumerator = (await countyNamesDictionary.CreateEnumerableAsync(tx)).GetAsyncEnumerator();

                        while (await enumerator.MoveNextAsync(cancellationToken))
                        {
                            countyNames.Add(enumerator.Current);
                        }

                        await tx.CommitAsync();
                    }

                    foreach (KeyValuePair <int, string> county in countyNames)
                    {
                        IReliableDictionary <Guid, CountyDoctorStats> countyHealth =
                            await
                            this.StateManager.GetOrAddAsync <IReliableDictionary <Guid, CountyDoctorStats> >(
                                string.Format(CountyHealthDictionaryName, county.Key));

                        int  totalDoctorCount       = 0;
                        int  totalPatientCount      = 0;
                        long totalHealthReportCount = 0;
                        //double priorAvg = 0;
                        //double expandedAverage = 0;
                        //double newTotal = 0;

                        IList <KeyValuePair <Guid, CountyDoctorStats> > records = new List <KeyValuePair <Guid, CountyDoctorStats> >();

                        using (ITransaction tx = this.StateManager.CreateTransaction())
                        {
                            var enumerator = (await countyHealth.CreateEnumerableAsync(tx, EnumerationMode.Unordered)).GetAsyncEnumerator();

                            while (await enumerator.MoveNextAsync(cancellationToken))
                            {
                                records.Add(enumerator.Current);
                            }

                            await tx.CommitAsync();
                        }

                        foreach (KeyValuePair <Guid, CountyDoctorStats> item in records)
                        {
                            //expandedAverage = priorAvg * totalDoctorCount;
                            //newTotal = expandedAverage + item.Value.AverageHealthIndex.GetValue();

                            totalDoctorCount++;
                            totalPatientCount      += item.Value.PatientCount;
                            totalHealthReportCount += item.Value.HealthReportCount;

                            //priorAvg = newTotal / totalHealthReportCount;
                        }

                        HealthIndex avgHealth;

                        if (records.Count > 0)
                        {
                            avgHealth = this.indexCalculator.ComputeAverageIndex(records.Select(x => x.Value.AverageHealthIndex));
                        }
                        else
                        {
                            avgHealth = this.indexCalculator.ComputeIndex(-1);
                        }


                        CountyStatsViewModel payload = new CountyStatsViewModel(totalDoctorCount, totalPatientCount, totalHealthReportCount, avgHealth);

                        ServiceUriBuilder serviceUri = new ServiceUriBuilder(this.GetSetting("NationalServiceInstanceName"));

                        await FabricHttpClient.MakePostRequest <CountyStatsViewModel>(
                            serviceUri.ToUri(),
                            new ServicePartitionKey(),
                            "NationalEndpoint",
                            "/national/health/" + county.Key,
                            payload,
                            SerializationSelector.PBUF,
                            cancellationToken
                            );
                    }
                }
                catch (TimeoutException te)
                {
                    // transient error. Retry.
                    ServiceEventSource.Current.ServiceMessage(
                        this.Context,
                        "CountyService encountered an exception trying to send data to National Service: TimeoutException in RunAsync: {0}",
                        te.ToString());
                }
                catch (FabricNotReadableException fnre)
                {
                    ServiceEventSource.Current.ServiceMessage(
                        this.Context,
                        "CountyService encountered an exception trying to send data to National Service: TimeoutException in RunAsync: {0}",
                        fnre.ToString());// transient error. Retry.
                }
                catch (FabricTransientException fte)
                {
                    // transient error. Retry.
                    ServiceEventSource.Current.ServiceMessage(
                        this.Context,
                        "CountyService encountered an exception trying to send data to National Service: FabricTransientException in RunAsync: {0}",
                        fte.ToString());
                }
                catch (FabricNotPrimaryException)
                {
                    // not primary any more, time to quit.
                    return;
                }
                catch (HttpRequestException hre)
                {
                    ServiceEventSource.Current.ServiceMessage(
                        this.Context,
                        "CountyService encountered an exception trying to send data to National Service: HttpRequestException in RunAsync: {0}",
                        hre.ToString());
                }
                catch (ProtoException pbe)
                {
                    ServiceEventSource.Current.ServiceMessage(
                        this.Context,
                        "CountyService encountered an exception trying to send data to National Service: ProtoException in RunAsync: {0}",
                        pbe.ToString());
                }
                catch (Exception ex)
                {
                    ServiceEventSource.Current.ServiceMessage(this.Context, "{0}", ex.ToString());
                    throw;
                }
            }
        }