Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Convert cql-execution to async #271

Merged
merged 10 commits into from
Oct 4, 2022
32 changes: 22 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,14 @@ const psource = new cql.PatientSource([
}
]);

const result = executor.exec(psource);
console.log(JSON.stringify(result, undefined, 2));
executor
.exec(psource)
.then(result => {
console.log(JSON.stringify(result, undefined, 2));
})
.catch(err => {
console.error(err);
});
```

In the above file, we've assumed the JSON ELM JSON file for the measure is called
Expand Down Expand Up @@ -187,8 +193,14 @@ const psource = new cql.PatientSource([ {
'birthDate' : '2007-08-02T11:47'
} ]);

const result = executor.exec(psource);
console.log(JSON.stringify(result, undefined, 2));
executor
.exec(psource)
.then(result => {
console.log(JSON.stringify(result, undefined, 2));
})
.catch(err => {
console.error(err);
});

```

Expand Down Expand Up @@ -308,16 +320,16 @@ describe('And', () => {
setup(this, data);
});

it('should execute allTrue as true', function () {
this.allTrue.exec(this.ctx).should.be.true();
it('should execute allTrue as true', async function () {
should(await this.allTrue.exec(this.ctx)).be.true();
});

it('should execute someTrue as false', function () {
this.someTrue.exec(this.ctx).should.be.false();
it('should execute someTrue as false', async function () {
should(await this.someTrue.exec(this.ctx)).be.false();
});

it('should execute allFalse as false', function () {
this.allFalse.exec(this.ctx).should.be.false();
it('should execute allFalse as false', async function () {
should(await this.allFalse.exec(this.ctx)).be.false();
});
});
```
Expand Down
28 changes: 28 additions & 0 deletions V2_to_V3_MIGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
This document outlines the breaking changes contributed to `cql-execution` that will be included in a `v3.0.0` release of the library. This document will be updated as new breaking changes are contributed to the repository before finalizing a `v3.0.0` release.

## Async Conversion

[This pull request](https://github.com/cqframework/cql-execution/pull/271) converted the core execution code of `cql-execution` to be asynchronous. This enables a wider variety of [DataProviders](https://github.com/cqframework/cql-execution/blob/7ecb00b236903fc0816966e4ca8368d50d6afbc4/src/types/cql-patient.interfaces.ts#L8)
to integrate with `cql-execution`, as data can now be retrieved using asynchronous operations (e.g. HTTP requests, database lookups, etc.). This conversion requires a change in how an [Executor](https://github.com/cqframework/cql-execution/blob/master/src/runtime/executor.ts) is used in practice:

``` TypeScript
// v2.x.x usage
const result = executor.exec(patientSource);
// Do something with result

// v3.x.x usage
executor.exec(patientSource).then((result) => {
// Do something with result
})

// or

const result = await executor.exec(patientSource);
```

The above pattern applies to the `exec_expression` and `exec_patient_context` methods of the `Executor` class as well.

In addition, the above pull request also adds support for a [TerminologyProvider](https://github.com/cqframework/cql-execution/blob/9fd81cb6eec615048513fdc8927725f853e2c085/src/types/cql-code-service.interfaces.ts#L29) to use asynchronous implementations of the `findValueSet*` functions
No changes are needed to how one configures an `Executor` to enable this, as the underlying code will now safely handle functions that return a `Promise` or not.

**NOTE:** This asynchronous approach is designed to be backwards-compatible with existing synchronous patient sources (e.g. [cql-exec-fhir](https://github.com/cqframework/cql-exec-fhir)), the only difference being that `exec` needs to be called using the above pattern instead of synchronously.
4 changes: 2 additions & 2 deletions examples/browser/cql4browsers.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
<head>
<script src="cql4browsers.js"></script>
<script>
function exec() {
async function exec() {
f = document.getElementById('form');
eval('elm = ' + f.elm.value)
if (f.parameters.value.trim()) {
eval('params = ' + f.parameters.value)
} else {
params = {}
}
f.results.value = JSON.stringify(executeSimpleELM(elm, new cql.PatientSource([]), [], 'Math', '1', null, params), null, 2)
f.results.value = JSON.stringify(await executeSimpleELM(elm, new cql.PatientSource([]), [], 'Math', '1', null, params), null, 2)
}
</script>
</head>
Expand Down
Loading