public async Task NewAsync(string name, CountyRecord countyRecord)
        {
            ConditionalValue <DoctorActorState> result = await this.StateManager.TryGetStateAsync <DoctorActorState>("DoctorActorState");

            if (!result.HasValue)
            {
                DoctorActorState state = new DoctorActorState();

                state                   = new DoctorActorState();
                state.Name              = "Dr. " + name;
                state.CountyInfo        = countyRecord;
                state.HealthReportCount = 0;
                await this.RegisterReminderAsync(GenerateHealthDataAsyncReminder, null, TimeSpan.FromSeconds(this.random.Next(5, 15)), TimeSpan.FromSeconds(5));

                ActorEventSource.Current.ActorMessage(this, "Doctor created. ID: {0}. Name: {1}", this.Id.GetGuidId(), name);
                await this.StateManager.SetStateAsync("DoctorActorState", state);
            }
        }
        public async Task <DoctorDataViewModel> GetPatientsAsync()
        {
            try
            {
                ConditionalValue <DoctorActorState> doctorActorStateResult = await this.StateManager.TryGetStateAsync <DoctorActorState>("DoctorActorState");

                if (doctorActorStateResult.HasValue)
                {
                    DoctorActorState state = doctorActorStateResult.Value;

                    if (state.HealthReportCount == 0)
                    {
                        return(new DoctorDataViewModel(state.Name, 0, state.CountyInfo, Enumerable.Empty <PatientDataViewModel>()));
                    }

                    int patientAverage = await this.GetAveragePatientHealthInfoAsync();

                    ActorEventSource.Current.ActorMessage(
                        this,
                        "Doctor {0} sending doctor view for county {1} with average {2}",
                        this.Id.GetGuidId(),
                        state.CountyInfo,
                        patientAverage);

                    return(new DoctorDataViewModel(
                               state.Name,
                               patientAverage,
                               state.CountyInfo,
                               state.PersonHealthStatuses.Select(
                                   x =>
                                   new PatientDataViewModel(
                                       x.Key,
                                       x.Value.Name,
                                       this.indexCalculator.ComputeIndex(x.Value.HealthIndex),
                                       this.indexCalculator.ComputeIndex(x.Value.HeartRateIndex)))));
                }
            }
            catch (Exception e)
            {
                throw new ArgumentException(string.Format("Exception inside doctor actor {0}|{1}|{2}", this.Id, this.Id.Kind, e));
            }

            throw new ArgumentException(string.Format("No actor state in actor {0}", this.Id));
        }
        public async Task ReportHealthAsync(Guid personId, string personName, HealthIndex healthIndex, HealthIndex heartRateIndex)
        {
            ConditionalValue <DoctorActorState> doctorActorStateResult = await this.StateManager.TryGetStateAsync <DoctorActorState>("DoctorActorState");

            if (doctorActorStateResult.HasValue)
            {
                DoctorActorState state = doctorActorStateResult.Value;

                state.PersonHealthStatuses[personId] = new DoctorPatientState(personId, personName, healthIndex, heartRateIndex);
                state.HealthReportCount++;

                await this.StateManager.SetStateAsync <DoctorActorState>("DoctorActorState", state);

                ActorEventSource.Current.Message(
                    "DoctorActor {0} Recieved health report from band {1} with value {2}",
                    this.Id.GetGuidId(),
                    personId,
                    healthIndex);
            }

            return;
        }
        public async Task SendHealthReportToCountyAsync()
        {
            try
            {
                ConditionalValue <DoctorActorState> doctorStateResult = await this.StateManager.TryGetStateAsync <DoctorActorState>("DoctorActorState");

                if (doctorStateResult.HasValue)
                {
                    DoctorActorState state = doctorStateResult.Value;

                    if (state.PersonHealthStatuses.Count > 0)
                    {
                        DoctorStatsViewModel payload = new DoctorStatsViewModel(
                            state.PersonHealthStatuses.Count,
                            state.HealthReportCount,
                            await this.GetAveragePatientHealthInfoAsync(),
                            state.Name);

                        ServicePartitionKey partitionKey = new ServicePartitionKey(state.CountyInfo.CountyId);
                        Guid id = this.Id.GetGuidId();

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

                        await servicePartitionClient.InvokeWithRetryAsync(
                            client =>
                        {
                            Uri serviceAddress = new Uri(
                                client.BaseAddress,
                                string.Format(
                                    "county/health/{0}/{1}",
                                    partitionKey.Value.ToString(),
                                    id));

                            HttpWebRequest request   = WebRequest.CreateHttp(serviceAddress);
                            request.Method           = "POST";
                            request.ContentType      = "application/json";
                            request.KeepAlive        = false;
                            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())
                                    {
                                        ActorEventSource.Current.Message("Doctor Sent Data to County: {0}", serviceAddress);
                                        return(Task.FromResult(true));
                                    }
                                }
                            }
                        }
                            );
                    }
                }
            }
            catch (Exception e)
            {
                ActorEventSource.Current.Message("DoctorActor failed to send health report to county service Outer Exception: {0}", e.ToString());
            }
        }