LiveBundle Overview
Applications such as patient dashboards need to quickly extract rich data from FHIR Endpoints. The volume of complex queries these applications generate can result in slow response times. Smile CDR provides a resource bundle caching service called “LiveBundle” to improve the performance of applications in situations like this. Administrators configure aggregation rules that store named FHIR Resource Bundles on the server and keep the list of references behind these bundles "warm" so they can be instantly retrieved by applications at runtime.
This is best illustrated with an example. Imagine a maternity ward with a patient dashboard that monitors the health of patients on the ward. It calculates a Modified Early Obstetric Warning Score (MEOWS) for each patient using 5 vitals.
Without using LiveBundle, this application would regularly query the FHIR repository for the most recent Observation for each vital for each patient.
In place of such queries, we could set up a LiveBundle to keep track of these vitals for us. To do this, we would first create a Watchlist called "MATERNITY". When a new patient is admitted to the ward, we add them to this Watchlist so LiveBundle will start tracking data for this patient. We would then create a new LiveBundle rule called "MEOWS" attached to this Watchlist that stores the most recent Observation for each vital. Then, when the app needs to display this dashboard, it would request the MEOWS LiveBundle for each patient to retrieve these stored Observations.
LiveBundle configuration is managed on a FHIR Storage module. When you enable the LiveBundle feature on a FHIR Storage module, Smile CDR adds an interceptor to that matches incoming resources against LiveBundle filters and aggregates rules. Enabling the LiveBundle feature on a FHIR Storage module also adds new LiveBundle Operations to FHIR Endpoint modules attached to that FHIR Storage module.
LiveBundle aggregation rules are configured using JavaScript. This JavaScript can either be stored in a file on disk or in the database. To store the LiveBundle rules in a file, specify an absolute filepath in livebundle_service.script.file. Alternatively, store the JavaScript in the database directly in livebundle_service.script.text.
See LiveBundle Rule Definition and LiveBundle Keepers for details on how LiveBundle aggregation rules are defined in JavaScript.
By default, LiveBundle watchlists are cached in memory and refreshed once per minute. If a matching resource for a just-added subscriber arrives on a different server within that minute, then that resource will be missed and not stored in that subscriber's bundle. For this reason, it's best to add subscribers at a time when new resources are not being submitted for them. This LiveBundle watchlist cache can be disabled by switching off the Watchlist Cache Enabled configuration option. When the cache is disabled, the matching operation for incoming resources is reversed: With cache enabled, first the resource is checked against the in-memory watchlist cache and then if it's on the list it is matched against the filter criteria. However, when the Watchlist Cache is disabled, first the resource will be matched against the Filter Criteria and then a database lookup checks to see if any subscriber references are on the watchlist for that Filter.
See LiveBundle API for details on how to call LiveBundle Operations on a FHIR Endpoint.
An overview of LiveBundle architecture is illustrated in the following diagram:
The top row of this diagram represents the flow of resources into the CDR. This means resources being created and updated, which are then used as sources of data for LiveBundles. It is described in the LiveBundle Aggregation section.
The bottom row represents requests for data stored in a LiveBundle, e.g. to display to a user in a dashboard. It is described in the LiveBundle Retrieval section.
A LiveBundle aggregation rule has two parts, a "Filter" and a "Keeper". The Filter determines whether an incoming resource triggers aggregation and the Keeper determines which references derived from that incoming resource is stored. A Filter has a Watchlist associated with it that maintains a list of Subscribers to that Filter.
In our MEOWS example, the Filter would match Observations that have a code for one of the vitals we are tracking. The MEOWS Keeper would be configured to store only the latest Observation for each vital.
The LiveBundle aggregation is triggered when any resource is created, updated or deleted on the FHIR Storage module. It checks to see if the resource matches any LiveBundle Filters. Matching follows these steps:
If the incoming resource matches, it is passed to the "Keeper" associated with that Filter. The Keeper adds and/or removes LiveBundle references according to its algorithm. See LiveBundle Keepers for details on how Keepers work.
The LiveBundle aggregation accumulates references for your Subscriber, so that they can later be retrieved as a resource bundle. A LiveBundle is retrieved by a Rule Name and SubscriberId.
In our MEOWS example, the Subscriber would be the maternity patient id and the Rule Name would be MEOWS.
LiveBundle retrieval follows these steps:
_include
parameter is on the LiveBundle request, those _include
d references are added to the list of references.Sometimes when a Watchlist and Rule are defined and a new Subscriber is added to that Watchlist, there will already be pre-existing data for that rule that should be accumulated for that Subscriber. This is called "Seeding" the bundle for that Subscriber. When a Subscriber is added to the Watchlist, Smile CDR searches the FHIR Storage repository for matching resources and aggregates a starting set of references for that Subscriber. Going forward, as new resources arrive, this list is updated.
In our MEOWS example, perhaps the patient was initially admitted to the Emergency ward where and vitals Observations had been collected for them. When that patient is added to the MATERNITY watchlist, the MEOWS LiveBundle would search for these Observations and seed the MEOWS bundle for that patient with their most recent vitals.
LiveBundle seeding works as follows:
The LiveBundle Troubleshooting Log can be helpful in diagnosing issues relating to Live Bundles.