[Test]
public async System.Threading.Tasks.Task TestFhirClientCallsInParallel()
{
// Generate patients
var patients = new List<Patient>();
for (int i = 1; i < 2000; i++)
{
patients.Add(new Patient
{
Name = new List<HumanName>
{
new HumanName
{
Family = $"Doe{i}",
Given = new List<string>
{
$"John{i}"
}
}
},
Identifier = new List<Identifier>
{
new Identifier(_patientRootOid, i.ToString())
{
Use = Identifier.IdentifierUse.Official,
Type = new CodeableConcept("http://hl7.org/fhir/v2/0203", "MR")
}
}
});
}
await System.Threading.Tasks.Task.Factory.StartNew(() =>
Parallel.ForEach(patients, new ParallelOptions
{
MaxDegreeOfParallelism = _numParallelThreads
}, async patient =>
{
// Use single FhirClient (instantiated as a private var)
var client = _fhirCient;
Console.WriteLine($"Processing Patient {patient.Identifier.FirstOrDefault()?.Value}");
// create patient
var createdPatient = await client.CreateAsync(patient, _retryPolicyFactory.CreateCatalystRetryPolicy());
Assert.NotNull(createdPatient);
Assert.IsTrue(patient.Identifier.IsExactly(createdPatient.Identifier));
// query for patient
var queriedPatientBundle = await client.SearchAsync<Patient>(new[] {$"identifier={patient.Identifier.FirstOrDefault()?.System}|{patient.Identifier.FirstOrDefault()?.Value}"}, _retryPolicyFactory.CreateCatalystRetryPolicy());
var queriedPatient = queriedPatientBundle?.Entry?.ByResourceType<Patient>()?.FirstOrDefault();
Assert.NotNull(queriedPatient);
Assert.IsTrue(patient.Identifier.IsExactly(queriedPatient.Identifier), $"First search for identifier {JsonConvert.SerializeObject(patient.Identifier)} but returned {JsonConvert.SerializeObject(queriedPatient.Identifier)}");
// update patient
queriedPatient.Name.FirstOrDefault()?.GivenElement.Add(new FhirString("Q"));
var updatedPatient = await client.UpdateAsync(queriedPatient, _retryPolicyFactory.CreateCatalystRetryPolicy());
Assert.NotNull(updatedPatient);
Assert.IsTrue(patient.Identifier.IsExactly(updatedPatient.Identifier));
// query for patient (2nd)
queriedPatientBundle = await client.SearchAsync<Patient>(new[] {$"identifier={patient.Identifier.FirstOrDefault()?.System}|{patient.Identifier.FirstOrDefault()?.Value}"}, _retryPolicyFactory.CreateCatalystRetryPolicy());
queriedPatient = queriedPatientBundle?.Entry?.ByResourceType<Patient>()?.FirstOrDefault();
Assert.NotNull(queriedPatient);
Assert.IsTrue(patient.Identifier.IsExactly(queriedPatient.Identifier), $"Second search for identifier {JsonConvert.SerializeObject(patient.Identifier)} but returned {JsonConvert.SerializeObject(queriedPatient.Identifier)}");
// update patient (2nd)
queriedPatient.Gender = AdministrativeGender.Male;
updatedPatient = await client.UpdateAsync(queriedPatient, _retryPolicyFactory.CreateCatalystRetryPolicy());
Assert.NotNull(updatedPatient);
Assert.IsTrue(patient.Identifier.IsExactly(updatedPatient.Identifier));
// query for patient
queriedPatientBundle = await client.SearchAsync<Patient>(new[] {$"identifier={patient.Identifier.FirstOrDefault()?.System}|{patient.Identifier.FirstOrDefault()?.Value}"}, _retryPolicyFactory.CreateCatalystRetryPolicy());
queriedPatient = queriedPatientBundle?.Entry?.ByResourceType<Patient>()?.FirstOrDefault();
Assert.NotNull(queriedPatient);
Assert.IsTrue(patient.Identifier.IsExactly(queriedPatient.Identifier), $"Third search for identifier {JsonConvert.SerializeObject(patient.Identifier)} but returned {JsonConvert.SerializeObject(queriedPatient.Identifier)}");
// delete patient
await client.DeleteAsync(queriedPatient, _retryPolicyFactory.CreateCatalystRetryPolicy());
})
);
}